2015-11-17 18:31:04

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 01/24] perf tools: Add 'perf-config' command

The perf configuration file contains many variables to change various
aspects of each of its tools, including output, disk usage, etc.
But looking through state of configuration is difficult and
there's no knowing what kind of other variables except variables
in perfconfig.example exist. So This patch adds 'perf-config'
command with '--list' option.

perf config [options]

display current perf config variables.
# perf config -l | --list

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Build | 1 +
tools/perf/builtin-config.c | 66 +++++++++++++++++++++++++++++++++++++++++++++
tools/perf/builtin.h | 1 +
tools/perf/command-list.txt | 1 +
tools/perf/perf.c | 1 +
5 files changed, 70 insertions(+)
create mode 100644 tools/perf/builtin-config.c

diff --git a/tools/perf/Build b/tools/perf/Build
index 7223745..2c7aaf2 100644
--- a/tools/perf/Build
+++ b/tools/perf/Build
@@ -1,5 +1,6 @@
perf-y += builtin-bench.o
perf-y += builtin-annotate.o
+perf-y += builtin-config.o
perf-y += builtin-diff.o
perf-y += builtin-evlist.o
perf-y += builtin-help.o
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
new file mode 100644
index 0000000..427ea7a
--- /dev/null
+++ b/tools/perf/builtin-config.c
@@ -0,0 +1,66 @@
+/*
+ * builtin-config.c
+ *
+ * Copyright (C) 2015, Taeung Song <[email protected]>
+ *
+ */
+#include "builtin.h"
+
+#include "perf.h"
+
+#include "util/cache.h"
+#include "util/parse-options.h"
+#include "util/util.h"
+#include "util/debug.h"
+
+static const char * const config_usage[] = {
+ "perf config [options]",
+ NULL
+};
+
+enum actions {
+ ACTION_LIST = 1
+} actions;
+
+static struct option config_options[] = {
+ OPT_SET_UINT('l', "list", &actions,
+ "show current config variables", ACTION_LIST),
+ OPT_END()
+};
+
+static int show_config(const char *key, const char *value,
+ void *cb __maybe_unused)
+{
+ if (value)
+ printf("%s=%s\n", key, value);
+ else
+ printf("%s\n", key);
+
+ return 0;
+}
+
+int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
+{
+ int ret = 0;
+
+ argc = parse_options(argc, argv, config_options, config_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+
+ switch (actions) {
+ case ACTION_LIST:
+ if (argc) {
+ pr_err("Error: takes no arguments\n");
+ parse_options_usage(config_usage, config_options, "l", 1);
+ } else {
+ ret = perf_config(show_config, NULL);
+ if (ret < 0)
+ pr_err("Nothing configured, "
+ "please check your ~/.perfconfig file\n");
+ }
+ break;
+ default:
+ usage_with_options(config_usage, config_options);
+ }
+
+ return ret;
+}
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 3688ad2..3f871b5 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -17,6 +17,7 @@ extern int cmd_annotate(int argc, const char **argv, const char *prefix);
extern int cmd_bench(int argc, const char **argv, const char *prefix);
extern int cmd_buildid_cache(int argc, const char **argv, const char *prefix);
extern int cmd_buildid_list(int argc, const char **argv, const char *prefix);
+extern int cmd_config(int argc, const char **argv, const char *prefix);
extern int cmd_diff(int argc, const char **argv, const char *prefix);
extern int cmd_evlist(int argc, const char **argv, const char *prefix);
extern int cmd_help(int argc, const char **argv, const char *prefix);
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index 00fcaf8..acc3ea7 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -9,6 +9,7 @@ perf-buildid-cache mainporcelain common
perf-buildid-list mainporcelain common
perf-data mainporcelain common
perf-diff mainporcelain common
+perf-config mainporcelain common
perf-evlist mainporcelain common
perf-inject mainporcelain common
perf-kmem mainporcelain common
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 3d4c7c0..4bee53c 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -39,6 +39,7 @@ struct cmd_struct {
static struct cmd_struct commands[] = {
{ "buildid-cache", cmd_buildid_cache, 0 },
{ "buildid-list", cmd_buildid_list, 0 },
+ { "config", cmd_config, 0 },
{ "diff", cmd_diff, 0 },
{ "evlist", cmd_evlist, 0 },
{ "help", cmd_help, 0 },
--
1.9.1


2015-11-17 18:43:33

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 02/24] perf tools: Add perf-config document

Add perf-config document to describe the perf configuration
and a subcommand 'list'.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 103 +++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
create mode 100644 tools/perf/Documentation/perf-config.txt

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
new file mode 100644
index 0000000..dfdab9c
--- /dev/null
+++ b/tools/perf/Documentation/perf-config.txt
@@ -0,0 +1,103 @@
+perf-config(1)
+==============
+
+NAME
+----
+perf-config - Get and set variables in a configuration file.
+
+SYNOPSIS
+--------
+[verse]
+'perf config' -l | --list
+
+DESCRIPTION
+-----------
+You can manage variables in a configuration file with this command.
+
+OPTIONS
+-------
+
+-l::
+--list::
+ Show current config variables, name and value, for all sections.
+
+CONFIGURATION FILE
+------------------
+
+The perf configuration file contains many variables to change various
+aspects of each of its tools, including output, disk usage, etc.
+The '$HOME/.perfconfig' file is used to store a per-user configuration.
+The file '$(sysconfdir)/perfconfig' can be used to
+store a system-wide default configuration.
+
+Syntax
+~~~~~~
+
+The file consist of sections. A section starts with its name
+surrounded by square brackets and continues till the next section
+begins. Each variable must be in a section, and have the form
+'name = value', for example:
+
+ [section]
+ name1 = value1
+ name2 = value2
+
+Section names are case sensitive and can contain any characters except
+newline (double quote `"` and backslash have to be escaped as `\"` and `\\`,
+respectively). Section headers can't span multiple lines.
+
+Example
+~~~~~~~
+
+Given a $HOME/.perfconfig like this:
+
+#
+# This is the config file, and
+# a '#' and ';' character indicates a comment
+#
+
+[colors]
+ # Color variables
+ top = red, default
+ medium = green, default
+ normal = lightgray, default
+ selected = white, lightgray
+ code = blue, default
+ addr = magenta, default
+ root = white, blue
+
+[tui]
+ # Defaults if linked with libslang
+ report = on
+ annotate = on
+ top = on
+
+[buildid]
+ # Default, disable using /dev/null
+ dir = ~/.debug
+
+[annotate]
+ # Defaults
+ hide_src_code = false
+ use_offset = true
+ jump_arrows = true
+ show_nr_jumps = false
+
+[help]
+ # Format can be man, info, web or html
+ format = man
+ autocorrect = 0
+
+[ui]
+ show-headers = true
+
+[call-graph]
+ # fp (framepointer), dwarf
+ record-mode = fp
+ print-type = graph
+ order = caller
+ sort-key = function
+
+SEE ALSO
+--------
+linkperf:perf[1]
--
1.9.1

2015-11-17 18:42:54

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 03/24] perf config: Document variables for 'color' section in man page

Explain 'color' section and its variables.

'top', 'medium', 'normal', 'selected',
'code', 'addr' and 'root'.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 44 ++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index dfdab9c..84a982b 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -98,6 +98,50 @@ Given a $HOME/.perfconfig like this:
order = caller
sort-key = function

+Variables
+~~~~~~~~~
+
+colors.*::
+ The variables for customizing the colors used in the output for the
+ 'report', 'top' and annotate in the TUI. They should specify the
+ background and foreground colors, separated by a comma, for example:
+
+ medium = green, lightgray
+
+ If you want to use the color configured for you terminal, just leave it
+ as 'default', for example:
+
+ medium = default, lightgray
+
+ Available colors:
+ red, green, default, black, blue, white, magenta, lightgray
+
+ colors.top::
+ 'top' means a overhead percentage which is more than 5%.
+ And values of this variable specify percentage colors.
+ Basic key values are foreground-color 'red' and
+ background-color 'default'.
+ colors.medium::
+ 'medium' means a overhead percentage which has more than 0.5%.
+ Default values are 'green' and 'default'.
+ colors.normal::
+ 'normal' means the rest of overhead percentages
+ except 'top', 'medium', 'selected'.
+ Default values are 'lightgray' and 'default'.
+ colors.selected::
+ This selects the colors for the current entry in a list of entries
+ from sub-commands (top,report,annotate).
+ Default values are 'white' and 'lightgray'.
+ colors.code::
+ Colors for arrows and lines in jumps on assembly code listings
+ such as 'jns','jmp','jane',etc. Default values are 'blue', 'default'.
+ colors.addr::
+ This selects colors for addresses from 'annotate'.
+ Default values are 'magenta', 'default'.
+ colors.root::
+ Colors for headers in the output of a sub-command 'top'.
+ Default values are 'white', 'blue'.
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:31:10

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 04/24] perf config: Document variables for 'tui' and 'gtk' sections in man page

Explain 'tui' and 'gtk' sections and these variables.

'top', 'report' and 'annotate'

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 84a982b..ec30229 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -142,6 +142,15 @@ colors.*::
Colors for headers in the output of a sub-command 'top'.
Default values are 'white', 'blue'.

+tui.*, gtk.*::
+ Available subcommands are 'top', 'report' and 'annotate'.
+ These values are a boolean type, for example:
+
+ top = true
+
+ By setting value, TUI or GTK can be enabled or not. But it is needed
+ that perf detects the required library for them during build.
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:42:34

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 05/24] perf config: Document 'buildid.dir' variable in man page

Explain 'buildid.dir' variable.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index ec30229..b4ee205 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -151,6 +151,21 @@ tui.*, gtk.*::
By setting value, TUI or GTK can be enabled or not. But it is needed
that perf detects the required library for them during build.

+buildid.*::
+ buildid.dir::
+ Each executable and shared library in modern distributions comes with a
+ content based identifier that, if available, will be inserted in a
+ 'perf.data' file header to, at analysis time find what is needed to do
+ symbol resolution, code annotation, etc.
+
+ The recording tools also stores a hard link or copy in a per-user
+ directory, $HOME/.debug/, of binaries, shared libraries, /proc/kallsyms
+ and /proc/kcore files to be used at analysis time.
+
+ The buildid.dir variable can be used to either change this directory
+ cache location, or to disable it altogether. If you want to disable it,
+ set buildid.dir to /dev/null. The default is $HOME/.debug
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:31:15

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 06/24] perf config: Document variables for 'annotate' section in man page

Explain 'annotate' section and its variables.

'hide_src_code', 'use_offset', 'jump_arrows' and 'show_nr_jumps'.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 76 ++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index b4ee205..bfbeb34 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -166,6 +166,82 @@ buildid.*::
cache location, or to disable it altogether. If you want to disable it,
set buildid.dir to /dev/null. The default is $HOME/.debug

+annotate.*::
+ There're options which work with a 'annotate' sub-command.
+ These are in control of addresses, jump function, source code
+ in lines of assembly code from a specific program.
+
+ annotate.hide_src_code::
+ If a program which is analyzed has source code,
+ this option lets 'annotate' print a list of assembly code with the source code.
+ For example, let's see a part of a program. There're four lines.
+ If this option is 'true', they can be printed
+ without source code from a program as below.
+
+ │ push %rbp
+ │ mov %rsp,%rbp
+ │ sub $0x10,%rsp
+ │ mov (%rdi),%rdx
+
+ But if this option is 'false', source code of the part
+ can be also printed as below.
+
+ │ struct rb_node *rb_next(const struct rb_node *node)
+ │ {
+ │ push %rbp
+ │ mov %rsp,%rbp
+ │ sub $0x10,%rsp
+ │ struct rb_node *parent;
+ │
+ │ if (RB_EMPTY_NODE(node))
+ │ mov (%rdi),%rdx
+ │ return n;
+
+ annotate.use_offset::
+ Basing on a first address of a loaded function, offset can be used.
+ Instead of using original addresses of assembly code,
+ addresses subtracted from a base address can be printed.
+ Let's illustrate a example.
+ If a base address is 0XFFFFFFFF81624d50 as below,
+
+ ffffffff81624d50 <load0>
+
+ a address on assembly code has a specific absolute address as below
+
+ ffffffff816250b8:│ mov 0x8(%r14),%rdi
+
+ but if use_offset is 'true', a address subtracted from a base address is printed.
+ The default is true. This option is only applied to TUI.
+
+ 368:│ mov 0x8(%r14),%rdi
+
+ annotate.jump_arrows::
+ There can be jump instruction among assembly code.
+ Depending on a boolean value of jump_arrows,
+ arrows can be printed or not which represent
+ where do the instruction jump into as below.
+
+ │ ┌──jmp 1333
+ │ │ xchg %ax,%ax
+ │1330:│ mov %r15,%r10
+ │1333:└─→cmp %r15,%r14
+
+ If jump_arrow is 'false', the arrows isn't printed as below.
+
+ │ ↓ jmp 1333
+ │ xchg %ax,%ax
+ │1330: mov %r15,%r10
+ │1333: cmp %r15,%r14
+
+ annotate.show_nr_jumps::
+ Let's see a part of assembly code.
+
+ │1382: movb $0x1,-0x270(%rbp)
+
+ If use this, the number of branches branching to that address can be printed as below.
+
+ │1 1382: movb $0x1,-0x270(%rbp)
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:31:19

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 07/24] perf config: Document variables for 'help' section in man page

Explain 'help.format' and 'help.autocorrect' variables.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index bfbeb34..88e9b88 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -242,6 +242,27 @@ annotate.*::

│1 1382: movb $0x1,-0x270(%rbp)

+help.*::
+ help.format:: = man
+ A format of manual page can be 'man', 'info', 'web' or 'html'.
+ 'man' is default.
+ help.autocorrect:: = 0
+ Automatically correct and execute mistyped commands after
+ waiting for the given number of deciseconds (0.1 sec).
+ Let's see a example. If a mistyped sub-command is executed like 'perf mistyped-command'
+ and this option is 0, the output is as below.
+
+ perf: 'mistyped-command' is not a perf-command. See 'perf --help'.
+
+ Or if this option is more than 1, the output can be such as.
+
+ WARNING: You called a perf program named 'mistyped-command', which does not exist.
+ Continuing under the assumption that you meant 'with-kcore'
+ in 0.1 seconds automatically...
+ Usage: perf-with-kcore <perf sub-command> <perf.data directory> [<sub-command options> [ -- <workload>]]
+ <perf sub-command> can be record, script, report or inject
+ or: perf-with-kcore fix_buildid_cache_permissions
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:31:27

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 08/24] perf config: Document 'hist.percentage' variable in man page

Explain 'hist.percentage' variable.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 88e9b88..b166b81 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -263,6 +263,23 @@ help.*::
<perf sub-command> can be record, script, report or inject
or: perf-with-kcore fix_buildid_cache_permissions

+hist.*::
+ hist.percentage::
+ This option control a way to calcurate overhead of filtered entries -
+ that means the value of this option is effective only if there's a
+ filter (by comm, dso or symbol name). Suppose a following example:
+
+ Overhead Symbols
+ ........ .......
+ 33.33% foo
+ 33.33% bar
+ 33.33% baz
+
+ This is an original overhead and we'll filter out the first 'foo'
+ entry. The value of 'relative' would increase the overhead of 'bar'
+ and 'baz' to 50.00% for each, while 'absolute' would show their
+ current overhead (33.33%).
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:41:47

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 09/24] perf config: Document 'ui.show-headers' variable in man page

Explain 'ui.show-headers' variable.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index b166b81..7d386d4 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -280,6 +280,11 @@ hist.*::
and 'baz' to 50.00% for each, while 'absolute' would show their
current overhead (33.33%).

+ui.*::
+ ui.show-headers::
+ There're columns as header 'Overhead', 'Children', 'Shared Object', 'Symbol', 'self'.
+ If this option is false, they are hiden. This option is only applied to TUI.
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:31:34

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 10/24] perf config: Document variables for 'call-graph' section in man page

Explain 'call-graph' section and its variables.

'record-mode', 'dump-size', 'print-type', 'order',
'sort-key', 'threshold' and 'print-limit'.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 65 ++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 7d386d4..dc659d6 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -285,6 +285,71 @@ ui.*::
There're columns as header 'Overhead', 'Children', 'Shared Object', 'Symbol', 'self'.
If this option is false, they are hiden. This option is only applied to TUI.

+call-graph.*::
+ When sub-commands 'top' and 'report' work with -g/—-children
+ there're options in control of call-graph.
+
+ call-graph.record-mode::
+ The record-mode can be 'fp' (frame pointer) and 'dwarf'.
+ The value of 'dwarf' is effective only if perf detect needed library
+ (libunwind or a recent version of libdw). Also it doesn't *require*
+ the dump-size option since it can use the default value of 8192 if
+ missing.
+
+ call-graph.dump-size::
+ The size of stack to dump in order to do post-unwinding. Default is 8192 (byte).
+ When using dwarf into record-mode this option should have a value.
+
+ call-graph.print-type::
+ The print-types can be graph (graph absolute), fractal (graph relative), flat.
+ This option controls a way to show overhead for each callchain entry.
+ Suppose a following example.
+
+ Overhead Symbols
+ ........ .......
+ 40.00% foo
+ |
+ --- foo
+ |
+ |--50.00%-- bar
+ | main
+ |
+ --50.00%-- baz
+ main
+
+ This output is a 'fractal' format. The 'foo' came from 'bar' and 'baz' exactly
+ half and half so 'fractal' shows 50.00% for each
+ (meaning that it assumes 100% total overhead of 'foo').
+
+ The 'graph' uses absolute overhead value of 'foo' as total so each of
+ 'bar' and 'baz' callchain will have 20.00% of overhead.
+
+ call-graph.order::
+ This option controls print order of callchains. The default is
+ 'callee' which means callee is printed at top and then followed by its
+ caller and so on. The 'caller' prints it in reverse order.
+
+ If this option is not set and report.children or top.children is
+ set to true (or the equivalent command line option is given),
+ the default value of this option is changed to 'caller' for the
+ execution of 'perf report' or 'perf top'. Other commands will
+ still default to 'callee'.
+
+ call-graph.sort-key::
+ The callchains are merged if they contain same information.
+ The sort-key option determines a way to compare the callchains.
+ A value of 'sort-key' can be 'function' or 'address'.
+ The default is 'function'.
+
+ call-graph.threshold::
+ When there're many callchains it'd print tons of lines. So perf omits
+ small callchains under a certain overhead (threshold) and this option
+ control the threashold. Default is 0.5 (%).
+
+ call-graph.print-limit::
+ This is another way to control the number of callchains printed for a
+ single entry. Default is 0 which means no limitation.
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:36:56

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 11/24] perf config: Document variables for 'report' section in man page

Explain 'report' section's variables.

'percent-limit', 'queue-size' and 'children'.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index dc659d6..b9f89dd 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -350,6 +350,23 @@ call-graph.*::
This is another way to control the number of callchains printed for a
single entry. Default is 0 which means no limitation.

+report.*::
+ report.percent-limit::
+ This one is mostly same as call-graph.threshold but works for
+ histogram entries. Entries have overhead lower than this percentage
+ will not be printed. Default is 0.
+ If percent-limit is 70, the output which has percentages of
+ each overhead above 70% can be printed.
+
+ report.queue-size::
+ option to setup the maximum allocation size for session's
+ ordered events queue, if not set there's no default limit.
+
+ report.children::
+ The children means that functions called from another function.
+ If the option is true, accumulate callchain of children and show total overhead.
+ Please refer to the perf-report manual. The default is true.
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:31:40

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 12/24] perf config: Document 'top.chidren' variable in man page

Explain 'top.children' variable.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index b9f89dd..344feb8 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -367,6 +367,12 @@ report.*::
If the option is true, accumulate callchain of children and show total overhead.
Please refer to the perf-report manual. The default is true.

+top.*::
+ top.children::
+ This option means same as report.children. So it is true,
+ the output of 'top' is rearranged by each overhead into children group.
+ The default is true.
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:35:11

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 13/24] perf config: Document 'man.viewer' variable in man page

Explain 'man.viewer' variable.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 344feb8..ea1d3e1 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -373,6 +373,11 @@ top.*::
the output of 'top' is rearranged by each overhead into children group.
The default is true.

+man.*::
+ man.viewer::
+ This option can assign a manual tool with which a subcommand 'help' work.
+ it can used as 'man', 'woman', 'konqueror'. Default value is 'man'.
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:31:44

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 14/24] perf config: Document 'pager.<subcommand>' variables in man page

Explain 'pager.<subcommand>' variables.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index ea1d3e1..8e7ffde 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -378,6 +378,11 @@ man.*::
This option can assign a manual tool with which a subcommand 'help' work.
it can used as 'man', 'woman', 'konqueror'. Default value is 'man'.

+pager.*::
+ pager.<subcommand>::
+ When a subcommand work as stdio instead of TUI, use pager with it.
+ Default value is 'true'.
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:34:39

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 15/24] perf config: Document 'kmem.default' variable in man page

Explain 'kmem.default' variable.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 8e7ffde..95255a0 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -383,6 +383,12 @@ pager.*::
When a subcommand work as stdio instead of TUI, use pager with it.
Default value is 'true'.

+kmem.*::
+ kmem.default::
+ This option can decide which allocator is analyzed between 'slab' and 'page'
+ without using options '--slab' and '--page'.
+ Default value is 'slab'.
+
SEE ALSO
--------
linkperf:perf[1]
--
1.9.1

2015-11-17 18:31:49

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 16/24] perf config: Add '--system' and '--user' options to select which config file is used

The file-options '--system' means $(sysconfdir)/perfconfig and
'--user' means $HOME/.perfconfig. If file-option isn't used,
both system and user config file is read.
The syntax examples are like below.

perf config [<file-option>] [options]

a specific config file.
# perf config --user | --system
or
both user and system config file.
# perf config

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 14 +++++++++++++-
tools/perf/builtin-config.c | 18 +++++++++++++++++-
tools/perf/util/cache.h | 3 +++
tools/perf/util/config.c | 4 ++--
4 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 95255a0..f556672 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -8,7 +8,7 @@ perf-config - Get and set variables in a configuration file.
SYNOPSIS
--------
[verse]
-'perf config' -l | --list
+'perf config' [<file-option>] -l | --list

DESCRIPTION
-----------
@@ -21,6 +21,14 @@ OPTIONS
--list::
Show current config variables, name and value, for all sections.

+--user::
+ For writing and reading options: write to user
+ '$HOME/.perfconfig' file or read it.
+
+--system::
+ For writing and reading options: write to system-wide
+ '$(sysconfdir)/perfconfig' or read it.
+
CONFIGURATION FILE
------------------

@@ -30,6 +38,10 @@ The '$HOME/.perfconfig' file is used to store a per-user configuration.
The file '$(sysconfdir)/perfconfig' can be used to
store a system-wide default configuration.

+When reading or writing, the values are read from the system and user
+configuration files by default, and options '--system' and '--user'
+can be used to tell the command to read from or write to only that location.
+
Syntax
~~~~~~

diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 427ea7a..e0f8b41 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -13,8 +13,10 @@
#include "util/util.h"
#include "util/debug.h"

+static bool use_system_config, use_user_config;
+
static const char * const config_usage[] = {
- "perf config [options]",
+ "perf config [<file-option>] [options]",
NULL
};

@@ -25,6 +27,8 @@ enum actions {
static struct option config_options[] = {
OPT_SET_UINT('l', "list", &actions,
"show current config variables", ACTION_LIST),
+ OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
+ OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
OPT_END()
};

@@ -46,6 +50,18 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
argc = parse_options(argc, argv, config_options, config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);

+ if (use_system_config && use_user_config) {
+ pr_err("Error: only one config file at a time\n");
+ parse_options_usage(config_usage, config_options, "user", 0);
+ parse_options_usage(NULL, config_options, "system", 0);
+ return -1;
+ }
+
+ if (use_system_config)
+ config_exclusive_filename = perf_etc_perfconfig();
+ else if (use_user_config)
+ config_exclusive_filename = mkpath("%s/.perfconfig", getenv("HOME"));
+
switch (actions) {
case ACTION_LIST:
if (argc) {
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index c861373..d1eb75f 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -19,6 +19,8 @@
#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"

+extern const char *config_exclusive_filename;
+
typedef int (*config_fn_t)(const char *, const char *, void *);
extern int perf_default_config(const char *, const char *, void *);
extern int perf_config(config_fn_t fn, void *);
@@ -27,6 +29,7 @@ extern u64 perf_config_u64(const char *, const char *);
extern int perf_config_bool(const char *, const char *);
extern int config_error_nonbool(const char *);
extern const char *perf_config_dirname(const char *, const char *);
+extern const char *perf_etc_perfconfig(void);

/* pager.c */
extern void setup_pager(void);
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 2e452ac..55ef373 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -26,7 +26,7 @@ static const char *config_file_name;
static int config_linenr;
static int config_file_eof;

-static const char *config_exclusive_filename;
+const char *config_exclusive_filename;

static int get_next_char(void)
{
@@ -434,7 +434,7 @@ static int perf_config_from_file(config_fn_t fn, const char *filename, void *dat
return ret;
}

-static const char *perf_etc_perfconfig(void)
+const char *perf_etc_perfconfig(void)
{
static const char *system_wide;
if (!system_wide)
--
1.9.1

2015-11-17 18:31:53

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 17/24] perf config: Collect configs to handle config variables

Collecting configs into list because of two reason.

First of all, if there are same variables both user
and system config file, they all will be printed
when 'list' command work. But if config variables are
duplicated, user config variables should only be printed
because it has priority.

Lastly, list into which configs is collected
will be required to keep and handle config variables
and values in the near furture. For example,
getting or setting functionality.

And change show_config() function.
Old show_config() worked depending on perf_config().
New show_config() work using collected configs list.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/builtin-config.c | 150 ++++++++++++++++++++++++++++++++++++++++++--
tools/perf/util/cache.h | 13 ++++
2 files changed, 158 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index e0f8b41..185aa5e 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -32,13 +32,148 @@ static struct option config_options[] = {
OPT_END()
};

-static int show_config(const char *key, const char *value,
- void *cb __maybe_unused)
+static struct config_section *find_section(struct list_head *sections,
+ const char *section_name)
{
+ struct config_section *section;
+
+ list_for_each_entry(section, sections, list)
+ if (!strcmp(section->name, section_name))
+ return section;
+
+ return NULL;
+}
+
+static struct config_element *find_element(const char *name,
+ struct config_section *section)
+{
+ struct config_element *element;
+
+ list_for_each_entry(element, &section->element_head, list)
+ if (!strcmp(element->name, name))
+ return element;
+
+ return NULL;
+}
+
+static void find_config(struct list_head *sections,
+ struct config_section **section,
+ struct config_element **element,
+ const char *section_name, const char *name)
+{
+ *section = find_section(sections, section_name);
+
+ if (*section != NULL)
+ *element = find_element(name, *section);
+ else
+ *element = NULL;
+}
+
+static struct config_section *init_section(const char *section_name)
+{
+ struct config_section *section;
+
+ section = zalloc(sizeof(*section));
+ if (!section)
+ return NULL;
+
+ INIT_LIST_HEAD(&section->element_head);
+ section->name = strdup(section_name);
+ if (!section->name) {
+ pr_err("%s: strdup failed\n", __func__);
+ free(section);
+ return NULL;
+ }
+
+ return section;
+}
+
+static int add_element(struct list_head *head,
+ const char *name, const char *value)
+{
+ struct config_element *element;
+
+ element = zalloc(sizeof(*element));
+ if (!element)
+ return -1;
+
+ element->name = strdup(name);
+ if (!element->name) {
+ pr_err("%s: strdup failed\n", __func__);
+ free(element);
+ return -1;
+ }
if (value)
- printf("%s=%s\n", key, value);
+ element->value = (char *)value;
else
- printf("%s\n", key);
+ element->value = NULL;
+
+ list_add_tail(&element->list, head);
+ return 0;
+}
+
+static int collect_current_config(const char *var, const char *value,
+ void *spec_sections)
+{
+ int ret = -1;
+ char *ptr, *key;
+ char *section_name, *name;
+ struct config_section *section = NULL;
+ struct config_element *element = NULL;
+ struct list_head *sections = (struct list_head *)spec_sections;
+
+ key = ptr = strdup(var);
+ if (!key) {
+ pr_err("%s: strdup failed\n", __func__);
+ return -1;
+ }
+
+ section_name = strsep(&ptr, ".");
+ name = ptr;
+ if (name == NULL || value == NULL)
+ goto out_err;
+
+ find_config(sections, &section, &element, section_name, name);
+
+ if (!section) {
+ section = init_section(section_name);
+ if (!section)
+ goto out_err;
+ list_add_tail(&section->list, sections);
+ }
+
+ value = strdup(value);
+ if (!value) {
+ pr_err("%s: strdup failed\n", __func__);
+ goto out_err;
+ }
+
+ if (!element)
+ add_element(&section->element_head, name, value);
+ else {
+ free(element->value);
+ element->value = (char *)value;
+ }
+
+ ret = 0;
+out_err:
+ free(key);
+ return ret;
+}
+
+static int show_config(struct list_head *sections)
+{
+ struct config_section *section;
+ struct config_element *element;
+
+ if (list_empty(sections))
+ return -1;
+ list_for_each_entry(section, sections, list) {
+ list_for_each_entry(element, &section->element_head, list) {
+ printf("%s.%s=%s\n", section->name,
+ element->name, element->value);
+ }
+ }

return 0;
}
@@ -46,6 +181,7 @@ static int show_config(const char *key, const char *value,
int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
{
int ret = 0;
+ struct list_head sections;

argc = parse_options(argc, argv, config_options, config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
@@ -57,18 +193,22 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
return -1;
}

+ INIT_LIST_HEAD(&sections);
+
if (use_system_config)
config_exclusive_filename = perf_etc_perfconfig();
else if (use_user_config)
config_exclusive_filename = mkpath("%s/.perfconfig", getenv("HOME"));

+ perf_config(collect_current_config, &sections);
+
switch (actions) {
case ACTION_LIST:
if (argc) {
pr_err("Error: takes no arguments\n");
parse_options_usage(config_usage, config_options, "l", 1);
} else {
- ret = perf_config(show_config, NULL);
+ ret = show_config(&sections);
if (ret < 0)
pr_err("Nothing configured, "
"please check your ~/.perfconfig file\n");
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index d1eb75f..e503371 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -1,6 +1,7 @@
#ifndef __PERF_CACHE_H
#define __PERF_CACHE_H

+#include <linux/list.h>
#include <stdbool.h>
#include "util.h"
#include "strbuf.h"
@@ -19,6 +20,18 @@
#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"

+struct config_element {
+ char *name;
+ char *value;
+ struct list_head list;
+};
+
+struct config_section {
+ char *name;
+ struct list_head element_head;
+ struct list_head list;
+};
+
extern const char *config_exclusive_filename;

typedef int (*config_fn_t)(const char *, const char *, void *);
--
1.9.1

2015-11-17 18:33:44

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 18/24] perf config: Add 'list-all' option to perf-config

'list-all' option is to display both current config variables
and all possible config variables with default values.
The syntax examples are like below

perf config [<file-option>] [options]

display all perf config with default values.
# perf config -a | --list-all

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 6 +
tools/perf/builtin-config.c | 222 ++++++++++++++++++++++++++++++-
2 files changed, 226 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index f556672..61f336b 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -9,6 +9,8 @@ SYNOPSIS
--------
[verse]
'perf config' [<file-option>] -l | --list
+or
+'perf config' [<file-option>] -a | --list-all

DESCRIPTION
-----------
@@ -29,6 +31,10 @@ OPTIONS
For writing and reading options: write to system-wide
'$(sysconfdir)/perfconfig' or read it.

+-a::
+--list-all::
+ Show current and all possible config variables with default values.
+
CONFIGURATION FILE
------------------

diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 185aa5e..1073ac4 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -21,17 +21,154 @@ static const char * const config_usage[] = {
};

enum actions {
- ACTION_LIST = 1
+ ACTION_LIST = 1,
+ ACTION_LIST_ALL
} actions;

static struct option config_options[] = {
OPT_SET_UINT('l', "list", &actions,
"show current config variables", ACTION_LIST),
+ OPT_SET_UINT('a', "list-all", &actions,
+ "show current and all possible config"
+ " variables with default values", ACTION_LIST_ALL),
OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
OPT_END()
};

+enum config_idx {
+ CONFIG_COLORS_TOP,
+ CONFIG_COLORS_MEDIUM,
+ CONFIG_COLORS_NORMAL,
+ CONFIG_COLORS_SELECTED,
+ CONFIG_COLORS_CODE,
+ CONFIG_COLORS_ADDR,
+ CONFIG_COLORS_ROOT,
+ CONFIG_TUI_REPORT,
+ CONFIG_TUI_ANNOTATE,
+ CONFIG_TUI_TOP,
+ CONFIG_BUILDID_DIR,
+ CONFIG_ANNOTATE_HIDE_SRC_CODE,
+ CONFIG_ANNOTATE_USE_OFFSET,
+ CONFIG_ANNOTATE_JUMP_ARROWS,
+ CONFIG_ANNOTATE_SHOW_NR_JUMPS,
+ CONFIG_GTK_ANNOTATE,
+ CONFIG_GTK_REPORT,
+ CONFIG_GTK_TOP,
+ CONFIG_PAGER_CMD,
+ CONFIG_PAGER_REPORT,
+ CONFIG_PAGER_ANNOTATE,
+ CONFIG_PAGER_TOP,
+ CONFIG_PAGER_DIFF,
+ CONFIG_HELP_FORMAT,
+ CONFIG_HELP_AUTOCORRECT,
+ CONFIG_HIST_PERCENTAGE,
+ CONFIG_UI_SHOW_HEADERS,
+ CONFIG_CALL_GRAPH_RECORD_MODE,
+ CONFIG_CALL_GRAPH_DUMP_SIZE,
+ CONFIG_CALL_GRAPH_PRINT_TYPE,
+ CONFIG_CALL_GRAPH_ORDER,
+ CONFIG_CALL_GRAPH_SORT_KEY,
+ CONFIG_CALL_GRAPH_THRESHOLD,
+ CONFIG_CALL_GRAPH_PRINT_LIMIT,
+ CONFIG_REPORT_CHILDREN,
+ CONFIG_REPORT_PERCENT_LIMIT,
+ CONFIG_REPORT_QUEUE_SIZE,
+ CONFIG_TOP_CHILDREN,
+ CONFIG_MAN_VIEWER,
+ CONFIG_KMEM_DEFAULT,
+};
+
+enum config_type {
+ CONFIG_TYPE_BOOL,
+ CONFIG_TYPE_INT,
+ CONFIG_TYPE_LONG,
+ CONFIG_TYPE_U64,
+ CONFIG_TYPE_FLOAT,
+ CONFIG_TYPE_DOUBLE,
+ CONFIG_TYPE_STRING,
+ /* special type */
+ CONFIG_END
+};
+
+struct config_item {
+ const char *section;
+ const char *name;
+ union {
+ bool b;
+ int i;
+ u32 l;
+ u64 ll;
+ float f;
+ double d;
+ const char *s;
+ } value;
+ enum config_type type;
+};
+
+#define CONF_VAR(_sec, _name, _field, _val, _type) \
+ { .section = _sec, .name = _name, .value._field = _val, .type = _type }
+
+#define CONF_BOOL_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, b, _val, CONFIG_TYPE_BOOL)
+#define CONF_INT_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, i, _val, CONFIG_TYPE_INT)
+#define CONF_LONG_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, l, _val, CONFIG_TYPE_LONG)
+#define CONF_U64_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, ll, _val, CONFIG_TYPE_U64)
+#define CONF_FLOAT_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, f, _val, CONFIG_TYPE_FLOAT)
+#define CONF_DOUBLE_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, d, _val, CONFIG_TYPE_DOUBLE)
+#define CONF_STR_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, s, _val, CONFIG_TYPE_STRING)
+#define CONF_END() { .type = CONFIG_END }
+
+struct config_item default_configs[] = {
+ CONF_STR_VAR(COLORS_TOP, "colors", "top", "red, default"),
+ CONF_STR_VAR(COLORS_MEDIUM, "colors", "medium", "green, default"),
+ CONF_STR_VAR(COLORS_NORMAL, "colors", "normal", "lightgray, default"),
+ CONF_STR_VAR(COLORS_SELECTED, "colors", "selected", "white, lightgray"),
+ CONF_STR_VAR(COLORS_CODE, "colors", "code", "blue, default"),
+ CONF_STR_VAR(COLORS_ADDR, "colors", "addr", "magenta, default"),
+ CONF_STR_VAR(COLORS_ROOT, "colors", "root", "white, blue"),
+ CONF_BOOL_VAR(TUI_REPORT, "tui", "report", true),
+ CONF_BOOL_VAR(TUI_ANNOTATE, "tui", "annotate", true),
+ CONF_BOOL_VAR(TUI_TOP, "tui", "top", true),
+ CONF_STR_VAR(BUILDID_DIR, "buildid", "dir", "~/.debug"),
+ CONF_BOOL_VAR(ANNOTATE_HIDE_SRC_CODE, "annotate", "hide_src_code", false),
+ CONF_BOOL_VAR(ANNOTATE_USE_OFFSET, "annotate", "use_offset", true),
+ CONF_BOOL_VAR(ANNOTATE_JUMP_ARROWS, "annotate", "jump_arrows", true),
+ CONF_BOOL_VAR(ANNOTATE_SHOW_NR_JUMPS, "annotate", "show_nr_jumps", false),
+ CONF_BOOL_VAR(GTK_ANNOTATE, "gtk", "annotate", false),
+ CONF_BOOL_VAR(GTK_REPORT, "gtk", "report", false),
+ CONF_BOOL_VAR(GTK_TOP, "gtk", "top", false),
+ CONF_BOOL_VAR(PAGER_CMD, "pager", "cmd", true),
+ CONF_BOOL_VAR(PAGER_REPORT, "pager", "report", true),
+ CONF_BOOL_VAR(PAGER_ANNOTATE, "pager", "annotate", true),
+ CONF_BOOL_VAR(PAGER_TOP, "pager", "top", true),
+ CONF_BOOL_VAR(PAGER_DIFF, "pager", "diff", true),
+ CONF_STR_VAR(HELP_FORMAT, "help", "format", "man"),
+ CONF_INT_VAR(HELP_AUTOCORRECT, "help", "autocorrect", 0),
+ CONF_STR_VAR(HIST_PERCENTAGE, "hist", "percentage", "absolute"),
+ CONF_BOOL_VAR(UI_SHOW_HEADERS, "ui", "show-headers", true),
+ CONF_STR_VAR(CALL_GRAPH_RECORD_MODE, "call-graph", "record-mode", "fp"),
+ CONF_LONG_VAR(CALL_GRAPH_DUMP_SIZE, "call-graph", "dump-size", 8192),
+ CONF_STR_VAR(CALL_GRAPH_PRINT_TYPE, "call-graph", "print-type", "graph"),
+ CONF_STR_VAR(CALL_GRAPH_ORDER, "call-graph", "order", "callee"),
+ CONF_STR_VAR(CALL_GRAPH_SORT_KEY, "call-graph", "sort-key", "function"),
+ CONF_DOUBLE_VAR(CALL_GRAPH_THRESHOLD, "call-graph", "threshold", 0.5),
+ CONF_LONG_VAR(CALL_GRAPH_PRINT_LIMIT, "call-graph", "print-limit", 0),
+ CONF_BOOL_VAR(REPORT_CHILDREN, "report", "children", true),
+ CONF_FLOAT_VAR(REPORT_PERCENT_LIMIT, "report", "percent-limit", 0),
+ CONF_U64_VAR(REPORT_QUEUE_SIZE, "report", "queue-size", 0),
+ CONF_BOOL_VAR(TOP_CHILDREN, "top", "children", true),
+ CONF_STR_VAR(MAN_VIEWER, "man", "viewer", "man"),
+ CONF_STR_VAR(KMEM_DEFAULT, "kmem", "default", "slab"),
+ CONF_END()
+};
+
static struct config_section *find_section(struct list_head *sections,
const char *section_name)
{
@@ -112,6 +249,75 @@ static int add_element(struct list_head *head,
return 0;
}

+static char *get_value(struct config_item *config)
+{
+ int ret = 0;
+ char *value;
+
+ if (config->type == CONFIG_TYPE_BOOL)
+ ret = asprintf(&value, "%s",
+ config->value.b ? "true" : "false");
+ else if (config->type == CONFIG_TYPE_INT)
+ ret = asprintf(&value, "%d", config->value.i);
+ else if (config->type == CONFIG_TYPE_LONG)
+ ret = asprintf(&value, "%u", config->value.l);
+ else if (config->type == CONFIG_TYPE_U64)
+ ret = asprintf(&value, "%"PRId64, config->value.ll);
+ else if (config->type == CONFIG_TYPE_FLOAT)
+ ret = asprintf(&value, "%f", config->value.f);
+ else if (config->type == CONFIG_TYPE_DOUBLE)
+ ret = asprintf(&value, "%f", config->value.d);
+ else
+ ret = asprintf(&value, "%s", config->value.s);
+
+ if (ret < 0)
+ return NULL;
+
+ return value;
+}
+
+static int show_all_config(struct list_head *sections)
+{
+ int i;
+ bool has_config;
+ struct config_section *section;
+ struct config_element *element;
+
+ for (i = 0; default_configs[i].type != CONFIG_END; i++) {
+ struct config_item *config = &default_configs[i];
+ find_config(sections, &section, &element,
+ config->section, config->name);
+
+ if (!element) {
+ char *value = get_value(config);
+
+ printf("%s.%s=%s\n", config->section, config->name, value);
+ free(value);
+ } else
+ printf("%s.%s=%s\n", section->name,
+ element->name, element->value);
+ }
+
+ /* Print config variables the default configsets haven't */
+ list_for_each_entry(section, sections, list) {
+ list_for_each_entry(element, &section->element_head, list) {
+ has_config = false;
+ for (i = 0; default_configs[i].type != CONFIG_END; i++) {
+ if (!strcmp(default_configs[i].section, section->name) &&
+ !strcmp(default_configs[i].name, element->name)) {
+ has_config = true;
+ break;
+ }
+ }
+ if (!has_config)
+ printf("%s.%s=%s\n", section->name,
+ element->name, element->value);
+ }
+ }
+
+ return 0;
+}
+
static int collect_current_config(const char *var, const char *value,
void *spec_sections)
{
@@ -183,6 +389,9 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
int ret = 0;
struct list_head sections;

+ set_option_flag(config_options, 'l', "list", PARSE_OPT_EXCLUSIVE);
+ set_option_flag(config_options, 'a', "list-all", PARSE_OPT_EXCLUSIVE);
+
argc = parse_options(argc, argv, config_options, config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);

@@ -203,10 +412,19 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
perf_config(collect_current_config, &sections);

switch (actions) {
+ case ACTION_LIST_ALL:
+ if (argc == 0) {
+ ret = show_all_config(&sections);
+ break;
+ }
+ /* fall through */
case ACTION_LIST:
if (argc) {
pr_err("Error: takes no arguments\n");
- parse_options_usage(config_usage, config_options, "l", 1);
+ if (actions == ACTION_LIST_ALL)
+ parse_options_usage(config_usage, config_options, "a", 1);
+ else
+ parse_options_usage(config_usage, config_options, "l", 1);
} else {
ret = show_config(&sections);
if (ret < 0)
--
1.9.1

2015-11-17 18:31:57

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 19/24] perf config: Add a option 'skel' to perf-config

Produce an skeleton with the possible config variables so
that one could then use $EDITOR ~/.perfconfig or
$(sysconfdir)/perfconfigand go on setting the knobs.

For the syntax examples,

# perf config -k | --skel
Initialize the possible config variables on config file.
# perf config --skel > ~/.perfconfig

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/builtin-config.c | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 1073ac4..2f8be59 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -22,7 +22,8 @@ static const char * const config_usage[] = {

enum actions {
ACTION_LIST = 1,
- ACTION_LIST_ALL
+ ACTION_LIST_ALL,
+ ACTION_SKEL
} actions;

static struct option config_options[] = {
@@ -31,6 +32,9 @@ static struct option config_options[] = {
OPT_SET_UINT('a', "list-all", &actions,
"show current and all possible config"
" variables with default values", ACTION_LIST_ALL),
+ OPT_SET_UINT('k', "skel", &actions,
+ "produce an skeleton with the possible"
+ " config variables", ACTION_SKEL),
OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
OPT_END()
@@ -276,6 +280,24 @@ static char *get_value(struct config_item *config)
return value;
}

+static int show_skel_config(void)
+{
+ char *section;
+
+ for (int i = 0; default_configs[i].type != CONFIG_END; i++) {
+ struct config_item *config = &default_configs[i];
+ char *value = get_value(config);
+ if (strcmp(section, config->section) != 0) {
+ section = (char *)config->section;
+ printf("\n[%s]\n", config->section);
+ }
+ printf("\t%s = %s\n", config->name, value);
+ free(value);
+ }
+
+ return 0;
+}
+
static int show_all_config(struct list_head *sections)
{
int i;
@@ -412,6 +434,12 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
perf_config(collect_current_config, &sections);

switch (actions) {
+ case ACTION_SKEL:
+ if (argc)
+ parse_options_usage(config_usage, config_options, "k", 1);
+ else
+ ret = show_skel_config();
+ break;
case ACTION_LIST_ALL:
if (argc == 0) {
ret = show_all_config(&sections);
--
1.9.1

2015-11-17 18:33:17

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 20/24] perf config: Add --verbose option for showing config description

To explain what each of variable options configures,
this option can be used with --skel option, i.e.

print the possible config variables with comments over each of them.
# perf config -k -v | --skel --verbose

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/builtin-config.c | 161 ++++++++++++++++++++++++++++----------------
1 file changed, 104 insertions(+), 57 deletions(-)

diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 2f8be59..c84ea7d 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -35,6 +35,8 @@ static struct option config_options[] = {
OPT_SET_UINT('k', "skel", &actions,
"produce an skeleton with the possible"
" config variables", ACTION_SKEL),
+ OPT_INCR('v', "verbose", &verbose, "Be more verbose"
+ " (show config description)"),
OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
OPT_END()
@@ -108,68 +110,111 @@ struct config_item {
const char *s;
} value;
enum config_type type;
+ const char *desc;
};

-#define CONF_VAR(_sec, _name, _field, _val, _type) \
- { .section = _sec, .name = _name, .value._field = _val, .type = _type }
-
-#define CONF_BOOL_VAR(_idx, _sec, _name, _val) \
- [CONFIG_##_idx] = CONF_VAR(_sec, _name, b, _val, CONFIG_TYPE_BOOL)
-#define CONF_INT_VAR(_idx, _sec, _name, _val) \
- [CONFIG_##_idx] = CONF_VAR(_sec, _name, i, _val, CONFIG_TYPE_INT)
-#define CONF_LONG_VAR(_idx, _sec, _name, _val) \
- [CONFIG_##_idx] = CONF_VAR(_sec, _name, l, _val, CONFIG_TYPE_LONG)
-#define CONF_U64_VAR(_idx, _sec, _name, _val) \
- [CONFIG_##_idx] = CONF_VAR(_sec, _name, ll, _val, CONFIG_TYPE_U64)
-#define CONF_FLOAT_VAR(_idx, _sec, _name, _val) \
- [CONFIG_##_idx] = CONF_VAR(_sec, _name, f, _val, CONFIG_TYPE_FLOAT)
-#define CONF_DOUBLE_VAR(_idx, _sec, _name, _val) \
- [CONFIG_##_idx] = CONF_VAR(_sec, _name, d, _val, CONFIG_TYPE_DOUBLE)
-#define CONF_STR_VAR(_idx, _sec, _name, _val) \
- [CONFIG_##_idx] = CONF_VAR(_sec, _name, s, _val, CONFIG_TYPE_STRING)
+#define CONF_VAR(_sec, _name, _field, _val, _type, _desc) \
+ { .section = _sec, .name = _name, .value._field = _val, .type = _type, .desc = _desc}
+
+#define CONF_BOOL_VAR(_idx, _sec, _name, _val, _desc) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, b, _val, CONFIG_TYPE_BOOL, _desc)
+#define CONF_INT_VAR(_idx, _sec, _name, _val, _desc) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, i, _val, CONFIG_TYPE_INT, _desc)
+#define CONF_LONG_VAR(_idx, _sec, _name, _val, _desc) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, l, _val, CONFIG_TYPE_LONG, _desc)
+#define CONF_U64_VAR(_idx, _sec, _name, _val, _desc) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, ll, _val, CONFIG_TYPE_U64, _desc)
+#define CONF_FLOAT_VAR(_idx, _sec, _name, _val, _desc) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, f, _val, CONFIG_TYPE_FLOAT, _desc)
+#define CONF_DOUBLE_VAR(_idx, _sec, _name, _val, _desc) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, d, _val, CONFIG_TYPE_DOUBLE, _desc)
+#define CONF_STR_VAR(_idx, _sec, _name, _val, _desc) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, s, _val, CONFIG_TYPE_STRING, _desc)
#define CONF_END() { .type = CONFIG_END }

struct config_item default_configs[] = {
- CONF_STR_VAR(COLORS_TOP, "colors", "top", "red, default"),
- CONF_STR_VAR(COLORS_MEDIUM, "colors", "medium", "green, default"),
- CONF_STR_VAR(COLORS_NORMAL, "colors", "normal", "lightgray, default"),
- CONF_STR_VAR(COLORS_SELECTED, "colors", "selected", "white, lightgray"),
- CONF_STR_VAR(COLORS_CODE, "colors", "code", "blue, default"),
- CONF_STR_VAR(COLORS_ADDR, "colors", "addr", "magenta, default"),
- CONF_STR_VAR(COLORS_ROOT, "colors", "root", "white, blue"),
- CONF_BOOL_VAR(TUI_REPORT, "tui", "report", true),
- CONF_BOOL_VAR(TUI_ANNOTATE, "tui", "annotate", true),
- CONF_BOOL_VAR(TUI_TOP, "tui", "top", true),
- CONF_STR_VAR(BUILDID_DIR, "buildid", "dir", "~/.debug"),
- CONF_BOOL_VAR(ANNOTATE_HIDE_SRC_CODE, "annotate", "hide_src_code", false),
- CONF_BOOL_VAR(ANNOTATE_USE_OFFSET, "annotate", "use_offset", true),
- CONF_BOOL_VAR(ANNOTATE_JUMP_ARROWS, "annotate", "jump_arrows", true),
- CONF_BOOL_VAR(ANNOTATE_SHOW_NR_JUMPS, "annotate", "show_nr_jumps", false),
- CONF_BOOL_VAR(GTK_ANNOTATE, "gtk", "annotate", false),
- CONF_BOOL_VAR(GTK_REPORT, "gtk", "report", false),
- CONF_BOOL_VAR(GTK_TOP, "gtk", "top", false),
- CONF_BOOL_VAR(PAGER_CMD, "pager", "cmd", true),
- CONF_BOOL_VAR(PAGER_REPORT, "pager", "report", true),
- CONF_BOOL_VAR(PAGER_ANNOTATE, "pager", "annotate", true),
- CONF_BOOL_VAR(PAGER_TOP, "pager", "top", true),
- CONF_BOOL_VAR(PAGER_DIFF, "pager", "diff", true),
- CONF_STR_VAR(HELP_FORMAT, "help", "format", "man"),
- CONF_INT_VAR(HELP_AUTOCORRECT, "help", "autocorrect", 0),
- CONF_STR_VAR(HIST_PERCENTAGE, "hist", "percentage", "absolute"),
- CONF_BOOL_VAR(UI_SHOW_HEADERS, "ui", "show-headers", true),
- CONF_STR_VAR(CALL_GRAPH_RECORD_MODE, "call-graph", "record-mode", "fp"),
- CONF_LONG_VAR(CALL_GRAPH_DUMP_SIZE, "call-graph", "dump-size", 8192),
- CONF_STR_VAR(CALL_GRAPH_PRINT_TYPE, "call-graph", "print-type", "graph"),
- CONF_STR_VAR(CALL_GRAPH_ORDER, "call-graph", "order", "callee"),
- CONF_STR_VAR(CALL_GRAPH_SORT_KEY, "call-graph", "sort-key", "function"),
- CONF_DOUBLE_VAR(CALL_GRAPH_THRESHOLD, "call-graph", "threshold", 0.5),
- CONF_LONG_VAR(CALL_GRAPH_PRINT_LIMIT, "call-graph", "print-limit", 0),
- CONF_BOOL_VAR(REPORT_CHILDREN, "report", "children", true),
- CONF_FLOAT_VAR(REPORT_PERCENT_LIMIT, "report", "percent-limit", 0),
- CONF_U64_VAR(REPORT_QUEUE_SIZE, "report", "queue-size", 0),
- CONF_BOOL_VAR(TOP_CHILDREN, "top", "children", true),
- CONF_STR_VAR(MAN_VIEWER, "man", "viewer", "man"),
- CONF_STR_VAR(KMEM_DEFAULT, "kmem", "default", "slab"),
+ CONF_STR_VAR(COLORS_TOP, "colors", "top", "red, default",
+ "A overhead percentage which is more than 5%"),
+ CONF_STR_VAR(COLORS_MEDIUM, "colors", "medium", "green, default",
+ "A overhead percentage which has more than 0.5%"),
+ CONF_STR_VAR(COLORS_NORMAL, "colors", "normal", "lightgray, default",
+ "The rest of overhead percentages"),
+ CONF_STR_VAR(COLORS_SELECTED, "colors", "selected", "white, lightgray",
+ "The current entry in a list of entries on TUI"),
+ CONF_STR_VAR(COLORS_CODE, "colors", "code", "blue, default",
+ "Arrows and lines in jumps on assembly code listings"),
+ CONF_STR_VAR(COLORS_ADDR, "colors", "addr", "magenta, default",
+ "Addresses from 'annotate"),
+ CONF_STR_VAR(COLORS_ROOT, "colors", "root", "white, blue",
+ "Headers in the output of a sub-command 'top'"),
+ CONF_BOOL_VAR(TUI_REPORT, "tui", "report", true,
+ "TUI can be enabled or not"),
+ CONF_BOOL_VAR(TUI_ANNOTATE, "tui", "annotate", true,
+ "TUI can be enabled or not"),
+ CONF_BOOL_VAR(TUI_TOP, "tui", "top", true,
+ "TUI can be enabled or not"),
+ CONF_STR_VAR(BUILDID_DIR, "buildid", "dir", "~/.debug",
+ "The directory location of binaries, shared libraries,"
+ " /proc/kallsyms and /proc/kcore files to be used"
+ " at analysis time"),
+ CONF_BOOL_VAR(ANNOTATE_HIDE_SRC_CODE, "annotate", "hide_src_code", false,
+ "Print a list of assembly code without the source code or not"),
+ CONF_BOOL_VAR(ANNOTATE_USE_OFFSET, "annotate", "use_offset", true,
+ "Addresses subtracted from a base address can be printed"),
+ CONF_BOOL_VAR(ANNOTATE_JUMP_ARROWS, "annotate", "jump_arrows", true,
+ "Arrows for jump instruction can be printed or not"),
+ CONF_BOOL_VAR(ANNOTATE_SHOW_NR_JUMPS, "annotate", "show_nr_jumps", false,
+ "The number of branches branching to that address can be printed"),
+ CONF_BOOL_VAR(GTK_ANNOTATE, "gtk", "annotate", false,
+ "GTK can be enabled or not"),
+ CONF_BOOL_VAR(GTK_REPORT, "gtk", "report", false,
+ "GTK can be enabled or not"),
+ CONF_BOOL_VAR(GTK_TOP, "gtk", "top", false,
+ "GTK can be enabled or not"),
+ CONF_BOOL_VAR(PAGER_CMD, "pager", "cmd", true,
+ "As stdio instead of TUI"),
+ CONF_BOOL_VAR(PAGER_REPORT, "pager", "report", true,
+ "As stdio instead of TUI"),
+ CONF_BOOL_VAR(PAGER_ANNOTATE, "pager", "annotate", true,
+ "As stdio instead of TUI"),
+ CONF_BOOL_VAR(PAGER_TOP, "pager", "top", true,
+ "As stdio instead of TUI"),
+ CONF_BOOL_VAR(PAGER_DIFF, "pager", "diff", true,
+ "As stdio instead of TUI"),
+ CONF_STR_VAR(HELP_FORMAT, "help", "format", "man", "A format of manual page"),
+ CONF_INT_VAR(HELP_AUTOCORRECT, "help", "autocorrect", 0,
+ "Automatically correct and execute mistyped commands after"
+ " waiting for the given number of deciseconds"),
+ CONF_STR_VAR(HIST_PERCENTAGE, "hist", "percentage", "absolute",
+ "Control a way to calcurate overhead of filtered entries"),
+ CONF_BOOL_VAR(UI_SHOW_HEADERS, "ui", "show-headers", true,
+ "Show or hide columns as header on TUI"),
+ CONF_STR_VAR(CALL_GRAPH_RECORD_MODE, "call-graph", "record-mode", "fp",
+ "The mode can be 'fp' (frame pointer) and 'dwarf'"),
+ CONF_LONG_VAR(CALL_GRAPH_DUMP_SIZE, "call-graph", "dump-size", 8192,
+ "The size of stack to dump in order to do post-unwinding"),
+ CONF_STR_VAR(CALL_GRAPH_PRINT_TYPE, "call-graph", "print-type", "graph",
+ "The type can be graph (graph absolute), fractal (graph relative), fla"),
+ CONF_STR_VAR(CALL_GRAPH_ORDER, "call-graph", "order", "callee",
+ "Controls print order of callchains (callee or caller)"),
+ CONF_STR_VAR(CALL_GRAPH_SORT_KEY, "call-graph", "sort-key", "function",
+ "It can be 'function' or 'address'"),
+ CONF_DOUBLE_VAR(CALL_GRAPH_THRESHOLD, "call-graph", "threshold", 0.5,
+ "Small callchains can be omitted under a certain overhead (threshold)"),
+ CONF_LONG_VAR(CALL_GRAPH_PRINT_LIMIT, "call-graph", "print-limit", 0,
+ "Control the number of callchains printed for a single entry"),
+ CONF_BOOL_VAR(REPORT_CHILDREN, "report", "children", true,
+ "Accumulate callchain of children and show total overhead or not"),
+ CONF_FLOAT_VAR(REPORT_PERCENT_LIMIT, "report", "percent-limit", 0,
+ "Entries have overhead lower than this percentage will not be printed"),
+ CONF_U64_VAR(REPORT_QUEUE_SIZE, "report", "queue-size", 0,
+ "The maximum allocation size for session's ordered events queue"),
+ CONF_BOOL_VAR(TOP_CHILDREN, "top", "children", true,
+ "Similar as report.children"),
+ CONF_STR_VAR(MAN_VIEWER, "man", "viewer", "man",
+ "Select manual tools that work a sub-command 'help'"),
+ CONF_STR_VAR(KMEM_DEFAULT, "kmem", "default", "slab",
+ "Which allocator is analyzed between 'slab' and 'page"),
CONF_END()
};

@@ -291,6 +336,8 @@ static int show_skel_config(void)
section = (char *)config->section;
printf("\n[%s]\n", config->section);
}
+ if (verbose)
+ printf("\t# %s\n", config->desc);
printf("\t%s = %s\n", config->name, value);
free(value);
}
--
1.9.1

2015-11-17 18:32:03

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 21/24] perf config: Add 'get' functionality

This patch consists of functions
which can get specific config variables.
For the syntax examples,

perf config [<file-option>] [section.name ...]

display key-value pairs of specific config variables
# perf config report.queue-size report.children

In addition, the functionality can work with --verbose option
to show the config description, i.e.

# perf config -v report.queue-size

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 2 +
tools/perf/builtin-config.c | 83 ++++++++++++++++++++++++++++++--
tools/perf/util/cache.h | 1 +
3 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 61f336b..ef4ddf6 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -8,6 +8,8 @@ perf-config - Get and set variables in a configuration file.
SYNOPSIS
--------
[verse]
+'perf config' [<file-option>] [section.name ...]
+or
'perf config' [<file-option>] -l | --list
or
'perf config' [<file-option>] -a | --list-all
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index c84ea7d..f36ac4b 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -16,7 +16,7 @@
static bool use_system_config, use_user_config;

static const char * const config_usage[] = {
- "perf config [<file-option>] [options]",
+ "perf config [<file-option>] [options] [section.name ...]",
NULL
};

@@ -387,6 +387,40 @@ static int show_all_config(struct list_head *sections)
return 0;
}

+static int show_spec_config(struct list_head *sections,
+ const char *section_name, const char *name)
+{
+ int i;
+ struct config_section *section = NULL;
+ struct config_element *element = NULL;
+
+ find_config(sections, &section, &element, section_name, name);
+
+ if (section && element) {
+ printf("%s.%s=%s\n", section->name,
+ element->name, element->value);
+ return 0;
+ }
+
+ for (i = 0; default_configs[i].type != CONFIG_END; i++) {
+ struct config_item *config = &default_configs[i];
+
+ if (!strcmp(config->section, section_name) &&
+ !strcmp(config->name, name)) {
+ char *value = get_value(config);
+
+ if (verbose)
+ printf("# %s\n", config->desc);
+ printf("%s.%s=%s (default)\n", config->section,
+ config->name, value);
+ free(value);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
static int collect_current_config(const char *var, const char *value,
void *spec_sections)
{
@@ -436,6 +470,43 @@ out_err:
return ret;
}

+static int perf_configset_with_option(configset_fn_t fn, struct list_head *sections,
+ const char *var)
+{
+ int ret = -1;
+ char *ptr, *key;
+ const char *last_dot;
+ char *section_name, *name;
+
+ key = ptr = strdup(var);
+ if (!key) {
+ pr_err("%s: strdup failed\n", __func__);
+ return -1;
+ }
+ last_dot = strchr(key, '.');
+ /*
+ * Since "key" actually contains the section name and the real
+ * key name separated by a dot, we have to know where the dot is.
+ */
+ if (last_dot == NULL || last_dot == key) {
+ pr_err("The config variable does not contain a section: %s\n", key);
+ goto out_err;
+ }
+ if (!last_dot[1]) {
+ pr_err("The config varible does not contain variable name: %s\n", key);
+ goto out_err;
+ }
+
+ section_name = strsep(&ptr, ".");
+ name = ptr;
+ fn(sections, section_name, name);
+ ret = 0;
+
+out_err:
+ free(key);
+ return ret;
+}
+
static int show_config(struct list_head *sections)
{
struct config_section *section;
@@ -455,7 +526,7 @@ static int show_config(struct list_head *sections)

int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
{
- int ret = 0;
+ int i, ret = 0;
struct list_head sections;

set_option_flag(config_options, 'l', "list", PARSE_OPT_EXCLUSIVE);
@@ -492,7 +563,6 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
ret = show_all_config(&sections);
break;
}
- /* fall through */
case ACTION_LIST:
if (argc) {
pr_err("Error: takes no arguments\n");
@@ -508,7 +578,12 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
}
break;
default:
- usage_with_options(config_usage, config_options);
+ if (argc)
+ for (i = 0; argv[i]; i++)
+ ret = perf_configset_with_option(show_spec_config, &sections,
+ argv[i]);
+ else
+ usage_with_options(config_usage, config_options);
}

return ret;
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index e503371..71aefed 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -35,6 +35,7 @@ struct config_section {
extern const char *config_exclusive_filename;

typedef int (*config_fn_t)(const char *, const char *, void *);
+typedef int (*configset_fn_t)(struct list_head *, const char *, const char *);
extern int perf_default_config(const char *, const char *, void *);
extern int perf_config(config_fn_t fn, void *);
extern int perf_config_int(const char *, const char *);
--
1.9.1

2015-11-17 18:32:50

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 22/24] perf config: Add 'set' feature

This patch consists of functions
which can set specific config variables.
For the syntax examples,

perf config [<file-option>] [options] [section.name[=value] ...]

set specific config variables
# perf config report.queue-size=100M report.children=true

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 2 +-
tools/perf/builtin-config.c | 127 +++++++++++++++++++++++++------
tools/perf/util/cache.h | 5 +-
tools/perf/util/config.c | 27 ++++++-
4 files changed, 134 insertions(+), 27 deletions(-)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index ef4ddf6..9892d11 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -8,7 +8,7 @@ perf-config - Get and set variables in a configuration file.
SYNOPSIS
--------
[verse]
-'perf config' [<file-option>] [section.name ...]
+'perf config' [<file-option>] [section.name[=value] ...]
or
'perf config' [<file-option>] -l | --list
or
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index f36ac4b..59d7842 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -16,7 +16,7 @@
static bool use_system_config, use_user_config;

static const char * const config_usage[] = {
- "perf config [<file-option>] [options] [section.name ...]",
+ "perf config [<file-option>] [options] [section.name[=value] ...]",
NULL
};

@@ -388,7 +388,9 @@ static int show_all_config(struct list_head *sections)
}

static int show_spec_config(struct list_head *sections,
- const char *section_name, const char *name)
+ const char *config_file_name __maybe_unused,
+ const char *section_name, const char *name,
+ char *value)
{
int i;
struct config_section *section = NULL;
@@ -407,7 +409,7 @@ static int show_spec_config(struct list_head *sections,

if (!strcmp(config->section, section_name) &&
!strcmp(config->name, name)) {
- char *value = get_value(config);
+ value = get_value(config);

if (verbose)
printf("# %s\n", config->desc);
@@ -421,6 +423,39 @@ static int show_spec_config(struct list_head *sections,
return -1;
}

+static int set_config(struct list_head *sections, const char *config_file_name,
+ const char *section_name, const char *name, char *value)
+{
+ struct config_section *section = NULL;
+ struct config_element *element = NULL;
+
+ find_config(sections, &section, &element, section_name, name);
+ if (value != NULL) {
+ value = strdup(value);
+ if (!value) {
+ pr_err("%s: strdup failed\n", __func__);
+ return -1;
+ }
+
+ /* if there isn't existent section, add a new section */
+ if (!section) {
+ section = init_section(section_name);
+ if (!section)
+ return -1;
+ list_add_tail(&section->list, sections);
+ }
+ /* if nothing to replace, add a new element which contains key-value pair. */
+ if (!element) {
+ add_element(&section->element_head, name, value);
+ } else {
+ free(element->value);
+ element->value = value;
+ }
+ }
+
+ return perf_configset_write_in_full(sections, config_file_name);
+}
+
static int collect_current_config(const char *var, const char *value,
void *spec_sections)
{
@@ -470,8 +505,10 @@ out_err:
return ret;
}

-static int perf_configset_with_option(configset_fn_t fn, struct list_head *sections,
- const char *var)
+static int perf_configset_with_option(configset_fn_t fn,
+ struct list_head *sections,
+ const char *config_file_name,
+ const char *var, char *value)
{
int ret = -1;
char *ptr, *key;
@@ -498,10 +535,24 @@ static int perf_configset_with_option(configset_fn_t fn, struct list_head *secti
}

section_name = strsep(&ptr, ".");
- name = ptr;
- fn(sections, section_name, name);
- ret = 0;
+ name = strsep(&ptr, "=");
+ if (!value) {
+ /* do nothing */
+ } else if (!strcmp(value, "=")) {
+ pr_err("The config variable does not contain a value: %s.%s\n",
+ section_name, name);
+ goto out_err;
+ } else {
+ value++;
+ name = strsep(&name, "=");
+ if (name[0] == '\0') {
+ pr_err("invalid key: %s\n", var);
+ goto out_err;
+ }
+ }

+ fn(sections, config_file_name, section_name, name, value);
+ ret = 0;
out_err:
free(key);
return ret;
@@ -527,7 +578,10 @@ static int show_config(struct list_head *sections)
int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
{
int i, ret = 0;
- struct list_head sections;
+ struct list_head *sections;
+ struct list_head all_sections, user_sections, system_sections;
+ const char *system_config = perf_etc_perfconfig();
+ char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));

set_option_flag(config_options, 'l', "list", PARSE_OPT_EXCLUSIVE);
set_option_flag(config_options, 'a', "list-all", PARSE_OPT_EXCLUSIVE);
@@ -542,14 +596,22 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
return -1;
}

- INIT_LIST_HEAD(&sections);
-
- if (use_system_config)
- config_exclusive_filename = perf_etc_perfconfig();
- else if (use_user_config)
- config_exclusive_filename = mkpath("%s/.perfconfig", getenv("HOME"));
-
- perf_config(collect_current_config, &sections);
+ INIT_LIST_HEAD(&user_sections);
+ INIT_LIST_HEAD(&system_sections);
+ perf_config_from_file(collect_current_config, user_config, &user_sections);
+ perf_config_from_file(collect_current_config, system_config, &system_sections);
+
+ if (use_system_config) {
+ sections = &system_sections;
+ config_exclusive_filename = system_config;
+ } else if (use_user_config) {
+ sections = &user_sections;
+ config_exclusive_filename = user_config;
+ } else {
+ sections = &all_sections;
+ INIT_LIST_HEAD(&all_sections);
+ perf_config(collect_current_config, &all_sections);
+ }

switch (actions) {
case ACTION_SKEL:
@@ -560,7 +622,7 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
break;
case ACTION_LIST_ALL:
if (argc == 0) {
- ret = show_all_config(&sections);
+ ret = show_all_config(sections);
break;
}
case ACTION_LIST:
@@ -571,18 +633,35 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
else
parse_options_usage(config_usage, config_options, "l", 1);
} else {
- ret = show_config(&sections);
+ ret = show_config(sections);
if (ret < 0)
pr_err("Nothing configured, "
"please check your ~/.perfconfig file\n");
}
break;
default:
- if (argc)
- for (i = 0; argv[i]; i++)
- ret = perf_configset_with_option(show_spec_config, &sections,
- argv[i]);
- else
+ if (argc) {
+ for (i = 0; argv[i]; i++) {
+ char *value = strchr(argv[i], '=');
+
+ if (value == NULL)
+ ret = perf_configset_with_option(show_spec_config,
+ sections, NULL,
+ argv[i], value);
+ else {
+ if (!use_system_config && !use_user_config)
+ ret = perf_configset_with_option(set_config,
+ &user_sections,
+ user_config,
+ argv[i], value);
+ else
+ ret = perf_configset_with_option(set_config,
+ sections,
+ config_exclusive_filename,
+ argv[i], value);
+ }
+ }
+ } else
usage_with_options(config_usage, config_options);
}

diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 71aefed..2ec958e 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -35,9 +35,12 @@ struct config_section {
extern const char *config_exclusive_filename;

typedef int (*config_fn_t)(const char *, const char *, void *);
-typedef int (*configset_fn_t)(struct list_head *, const char *, const char *);
+typedef int (*configset_fn_t)(struct list_head *, const char *,
+ const char *, const char *, char *);
+extern int perf_configset_write_in_full(struct list_head *sections, const char *file_name);
extern int perf_default_config(const char *, const char *, void *);
extern int perf_config(config_fn_t fn, void *);
+extern int perf_config_from_file(config_fn_t fn, const char *filename, void *data);
extern int perf_config_int(const char *, const char *);
extern u64 perf_config_u64(const char *, const char *);
extern int perf_config_bool(const char *, const char *);
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 55ef373..2111695 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -416,7 +416,7 @@ int perf_default_config(const char *var, const char *value,
return 0;
}

-static int perf_config_from_file(config_fn_t fn, const char *filename, void *data)
+int perf_config_from_file(config_fn_t fn, const char *filename, void *data)
{
int ret;
FILE *f = fopen(filename, "r");
@@ -506,6 +506,31 @@ out:
return ret;
}

+int perf_configset_write_in_full(struct list_head *sections, const char *file_name)
+{
+ struct config_section *section;
+ struct config_element *element;
+ const char *first_line = "# this file is auto-generated.";
+ FILE *fp = fopen(file_name, "w");
+
+ if (!fp)
+ return -1;
+
+ fprintf(fp, "%s\n", first_line);
+ /* overwrite configvariables */
+ list_for_each_entry(section, sections, list) {
+ fprintf(fp, "[%s]\n", section->name);
+ list_for_each_entry(element, &section->element_head, list) {
+ if (element->value)
+ fprintf(fp, "\t%s = %s\n",
+ element->name, element->value);
+ }
+ }
+ fclose(fp);
+
+ return 0;
+}
+
/*
* Call this to report error for your variable that should not
* get a boolean value (i.e. "[my] var" means "true").
--
1.9.1

2015-11-17 18:32:11

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 23/24] perf config: normalize a value depending on default type of it

Whether or not user mis-type wrong data type to set config,
normalize the value. If a config user enter isn't contained
in default configs, just pass as it is.
For the examples,

# perf config report.queue-size=1M
# perf config report.queue-size
report.queue-size=1048576

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/builtin-config.c | 54 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 49 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 59d7842..cf65250 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -423,6 +423,54 @@ static int show_spec_config(struct list_head *sections,
return -1;
}

+static char *normalize_value(const char *section_name, const char *name, const char *value)
+{
+ int i, ret = 0;
+ char *endptr;
+ char key[BUFSIZ];
+ char *normalized;
+
+ scnprintf(key, sizeof(key), "%s.%s", section_name, name);
+ for (i = 0; default_configs[i].type != CONFIG_END; i++) {
+ struct config_item *config = &default_configs[i];
+
+ if (!strcmp(config->section, section_name) &&
+ !strcmp(config->name, name)) {
+ if (config->type == CONFIG_TYPE_BOOL)
+ ret = asprintf(&normalized, "%s",
+ perf_config_bool(key, value) ? "true" : "false");
+ else if (config->type == CONFIG_TYPE_INT ||
+ config->type == CONFIG_TYPE_LONG)
+ ret = asprintf(&normalized, "%d",
+ perf_config_int(key, value));
+ else if (config->type == CONFIG_TYPE_U64)
+ ret = asprintf(&normalized, "%"PRId64,
+ perf_config_u64(key, value));
+ else if (config->type == CONFIG_TYPE_FLOAT)
+ ret = asprintf(&normalized, "%f",
+ strtof(value, &endptr));
+ else if (config->type == CONFIG_TYPE_DOUBLE)
+ ret = asprintf(&normalized, "%f",
+ strtod(value, &endptr));
+ else
+ ret = asprintf(&normalized, "%s", value);
+
+ if (ret < 0)
+ return NULL;
+
+ return normalized;
+ }
+ }
+
+ normalized = strdup(value);
+ if (!normalized) {
+ pr_err("%s: strdup failed\n", __func__);
+ return NULL;
+ }
+
+ return normalized;
+}
+
static int set_config(struct list_head *sections, const char *config_file_name,
const char *section_name, const char *name, char *value)
{
@@ -431,11 +479,7 @@ static int set_config(struct list_head *sections, const char *config_file_name,

find_config(sections, &section, &element, section_name, name);
if (value != NULL) {
- value = strdup(value);
- if (!value) {
- pr_err("%s: strdup failed\n", __func__);
- return -1;
- }
+ value = normalize_value(section_name, name, value);

/* if there isn't existent section, add a new section */
if (!section) {
--
1.9.1

2015-11-17 18:32:09

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 24/24] perf config: Add a option 'remove' to perf-config

A option 'remove' is to remove specific config variables.
For the syntax examples,

# perf config [<file-option>] -r | --remove [section.name ...]

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 6 ++++++
tools/perf/builtin-config.c | 37 ++++++++++++++++++++++++++++++--
2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 9892d11..7b33d96 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -13,6 +13,8 @@ or
'perf config' [<file-option>] -l | --list
or
'perf config' [<file-option>] -a | --list-all
+or
+'perf config' [<file-option>] -r | --remove [section.name ...]

DESCRIPTION
-----------
@@ -37,6 +39,10 @@ OPTIONS
--list-all::
Show current and all possible config variables with default values.

+-r::
+--remove::
+ Remove specific config variables.
+
CONFIGURATION FILE
------------------

diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index cf65250..53fe844 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -23,7 +23,8 @@ static const char * const config_usage[] = {
enum actions {
ACTION_LIST = 1,
ACTION_LIST_ALL,
- ACTION_SKEL
+ ACTION_SKEL,
+ ACTION_REMOVE
} actions;

static struct option config_options[] = {
@@ -35,6 +36,8 @@ static struct option config_options[] = {
OPT_SET_UINT('k', "skel", &actions,
"produce an skeleton with the possible"
" config variables", ACTION_SKEL),
+ OPT_SET_UINT('r', "remove", &actions,
+ "remove specific variables: [section.name ...]", ACTION_REMOVE),
OPT_INCR('v', "verbose", &verbose, "Be more verbose"
" (show config description)"),
OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
@@ -478,7 +481,13 @@ static int set_config(struct list_head *sections, const char *config_file_name,
struct config_element *element = NULL;

find_config(sections, &section, &element, section_name, name);
- if (value != NULL) {
+ if (!value) {
+ /* value == NULL means remove the variable */
+ if (section && element) {
+ free(element->value);
+ element->value = NULL;
+ }
+ } else {
value = normalize_value(section_name, name, value);

/* if there isn't existent section, add a new section */
@@ -629,6 +638,7 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)

set_option_flag(config_options, 'l', "list", PARSE_OPT_EXCLUSIVE);
set_option_flag(config_options, 'a', "list-all", PARSE_OPT_EXCLUSIVE);
+ set_option_flag(config_options, 'r', "remove", PARSE_OPT_EXCLUSIVE);

argc = parse_options(argc, argv, config_options, config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
@@ -658,6 +668,29 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
}

switch (actions) {
+ case ACTION_REMOVE:
+ if (argc) {
+ for (i = 0; argv[i]; i++) {
+ if (!use_system_config && !use_user_config) {
+ ret = perf_configset_with_option(set_config,
+ &system_sections,
+ system_config,
+ argv[i], NULL);
+ ret = perf_configset_with_option(set_config,
+ &user_sections,
+ user_config,
+ argv[i], NULL);
+ } else
+ ret = perf_configset_with_option(set_config, sections,
+ config_exclusive_filename,
+ argv[i], NULL);
+ }
+ } else {
+ pr_err("Error: Missing arguments\n");
+ parse_options_usage(config_usage, config_options, "r", 1);
+ return -1;
+ }
+ break;
case ACTION_SKEL:
if (argc)
parse_options_usage(config_usage, config_options, "k", 1);
--
1.9.1

2015-11-17 22:36:57

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 01/24] perf tools: Add 'perf-config' command

Hi Taeung,

On 2015년 11월 17일 오후 10시 53분 21초 GMT+09:00, Taeung Song <[email protected]> wrote:
>The perf configuration file contains many variables to change various
>aspects of each of its tools, including output, disk usage, etc.
>But looking through state of configuration is difficult and
>there's no knowing what kind of other variables except variables
>in perfconfig.example exist. So This patch adds 'perf-config'
>command with '--list' option.
>
> perf config [options]
>
> display current perf config variables.
> # perf config -l | --list
>
>Cc: Jiri Olsa <[email protected]>
>Signed-off-by: Taeung Song <[email protected]>

Acked-by: Namhyung Kim <[email protected]>

Thanks
Namhyung


>---
> tools/perf/Build | 1 +
>tools/perf/builtin-config.c | 66
>+++++++++++++++++++++++++++++++++++++++++++++
> tools/perf/builtin.h | 1 +
> tools/perf/command-list.txt | 1 +
> tools/perf/perf.c | 1 +
> 5 files changed, 70 insertions(+)
> create mode 100644 tools/perf/builtin-config.c
>
>diff --git a/tools/perf/Build b/tools/perf/Build
>index 7223745..2c7aaf2 100644
>--- a/tools/perf/Build
>+++ b/tools/perf/Build
>@@ -1,5 +1,6 @@
> perf-y += builtin-bench.o
> perf-y += builtin-annotate.o
>+perf-y += builtin-config.o
> perf-y += builtin-diff.o
> perf-y += builtin-evlist.o
> perf-y += builtin-help.o
>diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
>new file mode 100644
>index 0000000..427ea7a
>--- /dev/null
>+++ b/tools/perf/builtin-config.c
>@@ -0,0 +1,66 @@
>+/*
>+ * builtin-config.c
>+ *
>+ * Copyright (C) 2015, Taeung Song <[email protected]>
>+ *
>+ */
>+#include "builtin.h"
>+
>+#include "perf.h"
>+
>+#include "util/cache.h"
>+#include "util/parse-options.h"
>+#include "util/util.h"
>+#include "util/debug.h"
>+
>+static const char * const config_usage[] = {
>+ "perf config [options]",
>+ NULL
>+};
>+
>+enum actions {
>+ ACTION_LIST = 1
>+} actions;
>+
>+static struct option config_options[] = {
>+ OPT_SET_UINT('l', "list", &actions,
>+ "show current config variables", ACTION_LIST),
>+ OPT_END()
>+};
>+
>+static int show_config(const char *key, const char *value,
>+ void *cb __maybe_unused)
>+{
>+ if (value)
>+ printf("%s=%s\n", key, value);
>+ else
>+ printf("%s\n", key);
>+
>+ return 0;
>+}
>+
>+int cmd_config(int argc, const char **argv, const char *prefix
>__maybe_unused)
>+{
>+ int ret = 0;
>+
>+ argc = parse_options(argc, argv, config_options, config_usage,
>+ PARSE_OPT_STOP_AT_NON_OPTION);
>+
>+ switch (actions) {
>+ case ACTION_LIST:
>+ if (argc) {
>+ pr_err("Error: takes no arguments\n");
>+ parse_options_usage(config_usage, config_options, "l", 1);
>+ } else {
>+ ret = perf_config(show_config, NULL);
>+ if (ret < 0)
>+ pr_err("Nothing configured, "
>+ "please check your ~/.perfconfig file\n");
>+ }
>+ break;
>+ default:
>+ usage_with_options(config_usage, config_options);
>+ }
>+
>+ return ret;
>+}
>diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
>index 3688ad2..3f871b5 100644
>--- a/tools/perf/builtin.h
>+++ b/tools/perf/builtin.h
>@@ -17,6 +17,7 @@ extern int cmd_annotate(int argc, const char **argv,
>const char *prefix);
> extern int cmd_bench(int argc, const char **argv, const char *prefix);
>extern int cmd_buildid_cache(int argc, const char **argv, const char
>*prefix);
>extern int cmd_buildid_list(int argc, const char **argv, const char
>*prefix);
>+extern int cmd_config(int argc, const char **argv, const char
>*prefix);
> extern int cmd_diff(int argc, const char **argv, const char *prefix);
>extern int cmd_evlist(int argc, const char **argv, const char *prefix);
> extern int cmd_help(int argc, const char **argv, const char *prefix);
>diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
>index 00fcaf8..acc3ea7 100644
>--- a/tools/perf/command-list.txt
>+++ b/tools/perf/command-list.txt
>@@ -9,6 +9,7 @@ perf-buildid-cache mainporcelain common
> perf-buildid-list mainporcelain common
> perf-data mainporcelain common
> perf-diff mainporcelain common
>+perf-config mainporcelain common
> perf-evlist mainporcelain common
> perf-inject mainporcelain common
> perf-kmem mainporcelain common
>diff --git a/tools/perf/perf.c b/tools/perf/perf.c
>index 3d4c7c0..4bee53c 100644
>--- a/tools/perf/perf.c
>+++ b/tools/perf/perf.c
>@@ -39,6 +39,7 @@ struct cmd_struct {
> static struct cmd_struct commands[] = {
> { "buildid-cache", cmd_buildid_cache, 0 },
> { "buildid-list", cmd_buildid_list, 0 },
>+ { "config", cmd_config, 0 },
> { "diff", cmd_diff, 0 },
> { "evlist", cmd_evlist, 0 },
> { "help", cmd_help, 0 },


--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

2015-11-17 23:13:18

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 02/24] perf tools: Add perf-config document

On Tue, Nov 17, 2015 at 10:53:22PM +0900, Taeung Song wrote:
> Add perf-config document to describe the perf configuration
> and a subcommand 'list'.
>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>

Acked-by: Namhyung Kim <[email protected]>

Thanks,
Namhyung


> ---
> tools/perf/Documentation/perf-config.txt | 103 +++++++++++++++++++++++++++++++
> 1 file changed, 103 insertions(+)
> create mode 100644 tools/perf/Documentation/perf-config.txt
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> new file mode 100644
> index 0000000..dfdab9c
> --- /dev/null
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -0,0 +1,103 @@
> +perf-config(1)
> +==============
> +
> +NAME
> +----
> +perf-config - Get and set variables in a configuration file.
> +
> +SYNOPSIS
> +--------
> +[verse]
> +'perf config' -l | --list
> +
> +DESCRIPTION
> +-----------
> +You can manage variables in a configuration file with this command.
> +
> +OPTIONS
> +-------
> +
> +-l::
> +--list::
> + Show current config variables, name and value, for all sections.
> +
> +CONFIGURATION FILE
> +------------------
> +
> +The perf configuration file contains many variables to change various
> +aspects of each of its tools, including output, disk usage, etc.
> +The '$HOME/.perfconfig' file is used to store a per-user configuration.
> +The file '$(sysconfdir)/perfconfig' can be used to
> +store a system-wide default configuration.
> +
> +Syntax
> +~~~~~~
> +
> +The file consist of sections. A section starts with its name
> +surrounded by square brackets and continues till the next section
> +begins. Each variable must be in a section, and have the form
> +'name = value', for example:
> +
> + [section]
> + name1 = value1
> + name2 = value2
> +
> +Section names are case sensitive and can contain any characters except
> +newline (double quote `"` and backslash have to be escaped as `\"` and `\\`,
> +respectively). Section headers can't span multiple lines.
> +
> +Example
> +~~~~~~~
> +
> +Given a $HOME/.perfconfig like this:
> +
> +#
> +# This is the config file, and
> +# a '#' and ';' character indicates a comment
> +#
> +
> +[colors]
> + # Color variables
> + top = red, default
> + medium = green, default
> + normal = lightgray, default
> + selected = white, lightgray
> + code = blue, default
> + addr = magenta, default
> + root = white, blue
> +
> +[tui]
> + # Defaults if linked with libslang
> + report = on
> + annotate = on
> + top = on
> +
> +[buildid]
> + # Default, disable using /dev/null
> + dir = ~/.debug
> +
> +[annotate]
> + # Defaults
> + hide_src_code = false
> + use_offset = true
> + jump_arrows = true
> + show_nr_jumps = false
> +
> +[help]
> + # Format can be man, info, web or html
> + format = man
> + autocorrect = 0
> +
> +[ui]
> + show-headers = true
> +
> +[call-graph]
> + # fp (framepointer), dwarf
> + record-mode = fp
> + print-type = graph
> + order = caller
> + sort-key = function
> +
> +SEE ALSO
> +--------
> +linkperf:perf[1]
> --
> 1.9.1
>

2015-11-17 23:47:26

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 03/24] perf config: Document variables for 'color' section in man page

On Tue, Nov 17, 2015 at 10:53:23PM +0900, Taeung Song wrote:
> Explain 'color' section and its variables.
>
> 'top', 'medium', 'normal', 'selected',
> 'code', 'addr' and 'root'.
>
> Cc: Namhyung Kim <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 44 ++++++++++++++++++++++++++++++++
> 1 file changed, 44 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index dfdab9c..84a982b 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -98,6 +98,50 @@ Given a $HOME/.perfconfig like this:
> order = caller
> sort-key = function
>
> +Variables
> +~~~~~~~~~
> +
> +colors.*::
> + The variables for customizing the colors used in the output for the
> + 'report', 'top' and annotate in the TUI. They should specify the

The 'annotate' also needs to be surrounded by single quotes.


> + background and foreground colors, separated by a comma, for example:

I think 'foreground and background' is better due to the order.


> +
> + medium = green, lightgray
> +
> + If you want to use the color configured for you terminal, just leave it
> + as 'default', for example:
> +
> + medium = default, lightgray
> +
> + Available colors:
> + red, green, default, black, blue, white, magenta, lightgray

I don't know about the libslang color scheme, but it seems that the
standard color names like 'yellow', 'cyan' and 'gray' are also
available.


> +
> + colors.top::
> + 'top' means a overhead percentage which is more than 5%.
> + And values of this variable specify percentage colors.
> + Basic key values are foreground-color 'red' and
> + background-color 'default'.
> + colors.medium::
> + 'medium' means a overhead percentage which has more than 0.5%.
> + Default values are 'green' and 'default'.
> + colors.normal::
> + 'normal' means the rest of overhead percentages
> + except 'top', 'medium', 'selected'.
> + Default values are 'lightgray' and 'default'.
> + colors.selected::
> + This selects the colors for the current entry in a list of entries
> + from sub-commands (top,report,annotate).
> + Default values are 'white' and 'lightgray'.

Isn't it 'black' and 'lightgray'?


> + colors.code::
> + Colors for arrows and lines in jumps on assembly code listings
> + such as 'jns','jmp','jane',etc. Default values are 'blue', 'default'.

Hmm.. I thought this is for source code displayed with annotate
output, but it's only for jump arrows? Maybe it's better to rename
this then.. Anyway it's a different problem.


> + colors.addr::
> + This selects colors for addresses from 'annotate'.
> + Default values are 'magenta', 'default'.
> + colors.root::
> + Colors for headers in the output of a sub-command 'top'.

It also works for 'report'.

Thanks,
Namhyung


> + Default values are 'white', 'blue'.
> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 00:01:33

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 04/24] perf config: Document variables for 'tui' and 'gtk' sections in man page

On Tue, Nov 17, 2015 at 10:53:24PM +0900, Taeung Song wrote:
> Explain 'tui' and 'gtk' sections and these variables.
>
> 'top', 'report' and 'annotate'
>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>

Acked-by: Namhyung Kim <[email protected]>

Thanks,
Namhyung


> ---
> tools/perf/Documentation/perf-config.txt | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index 84a982b..ec30229 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -142,6 +142,15 @@ colors.*::
> Colors for headers in the output of a sub-command 'top'.
> Default values are 'white', 'blue'.
>
> +tui.*, gtk.*::
> + Available subcommands are 'top', 'report' and 'annotate'.
> + These values are a boolean type, for example:
> +
> + top = true
> +
> + By setting value, TUI or GTK can be enabled or not. But it is needed
> + that perf detects the required library for them during build.
> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 00:03:13

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 05/24] perf config: Document 'buildid.dir' variable in man page

On Tue, Nov 17, 2015 at 10:53:25PM +0900, Taeung Song wrote:
> Explain 'buildid.dir' variable.
>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>

Acked-by: Namhyung Kim <[email protected]>

Thanks,
Namhyung


> ---
> tools/perf/Documentation/perf-config.txt | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index ec30229..b4ee205 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -151,6 +151,21 @@ tui.*, gtk.*::
> By setting value, TUI or GTK can be enabled or not. But it is needed
> that perf detects the required library for them during build.
>
> +buildid.*::
> + buildid.dir::
> + Each executable and shared library in modern distributions comes with a
> + content based identifier that, if available, will be inserted in a
> + 'perf.data' file header to, at analysis time find what is needed to do
> + symbol resolution, code annotation, etc.
> +
> + The recording tools also stores a hard link or copy in a per-user
> + directory, $HOME/.debug/, of binaries, shared libraries, /proc/kallsyms
> + and /proc/kcore files to be used at analysis time.
> +
> + The buildid.dir variable can be used to either change this directory
> + cache location, or to disable it altogether. If you want to disable it,
> + set buildid.dir to /dev/null. The default is $HOME/.debug
> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 00:24:39

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 06/24] perf config: Document variables for 'annotate' section in man page

On Tue, Nov 17, 2015 at 10:53:26PM +0900, Taeung Song wrote:
> Explain 'annotate' section and its variables.
>
> 'hide_src_code', 'use_offset', 'jump_arrows' and 'show_nr_jumps'.

The 'show_linenr' and 'show_total_period' are missing. Also you'd
better to mention the default values for each option.

And some nitpicks below..

>
> Cc: Namhyung Kim <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 76 ++++++++++++++++++++++++++++++++
> 1 file changed, 76 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index b4ee205..bfbeb34 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -166,6 +166,82 @@ buildid.*::
> cache location, or to disable it altogether. If you want to disable it,
> set buildid.dir to /dev/null. The default is $HOME/.debug
>
> +annotate.*::
> + There're options which work with a 'annotate' sub-command.

AFAIK these options work only for TUI.


> + These are in control of addresses, jump function, source code
> + in lines of assembly code from a specific program.
> +
> + annotate.hide_src_code::
> + If a program which is analyzed has source code,
> + this option lets 'annotate' print a list of assembly code with the source code.
> + For example, let's see a part of a program. There're four lines.
> + If this option is 'true', they can be printed
> + without source code from a program as below.
> +
> + │ push %rbp
> + │ mov %rsp,%rbp
> + │ sub $0x10,%rsp
> + │ mov (%rdi),%rdx
> +
> + But if this option is 'false', source code of the part
> + can be also printed as below.
> +
> + │ struct rb_node *rb_next(const struct rb_node *node)
> + │ {
> + │ push %rbp
> + │ mov %rsp,%rbp
> + │ sub $0x10,%rsp
> + │ struct rb_node *parent;
> + │
> + │ if (RB_EMPTY_NODE(node))
> + │ mov (%rdi),%rdx
> + │ return n;
> +
> + annotate.use_offset::
> + Basing on a first address of a loaded function, offset can be used.
> + Instead of using original addresses of assembly code,
> + addresses subtracted from a base address can be printed.
> + Let's illustrate a example.

s/a example/an example/


> + If a base address is 0XFFFFFFFF81624d50 as below,
> +
> + ffffffff81624d50 <load0>
> +
> + a address on assembly code has a specific absolute address as below

s/a address/an address/


> +
> + ffffffff816250b8:│ mov 0x8(%r14),%rdi
> +
> + but if use_offset is 'true', a address subtracted from a base address is printed.

Ditto.


> + The default is true. This option is only applied to TUI.
> +
> + 368:│ mov 0x8(%r14),%rdi
> +
> + annotate.jump_arrows::
> + There can be jump instruction among assembly code.
> + Depending on a boolean value of jump_arrows,
> + arrows can be printed or not which represent
> + where do the instruction jump into as below.
> +
> + │ ┌──jmp 1333
> + │ │ xchg %ax,%ax
> + │1330:│ mov %r15,%r10
> + │1333:└─→cmp %r15,%r14
> +
> + If jump_arrow is 'false', the arrows isn't printed as below.
> +
> + │ ↓ jmp 1333
> + │ xchg %ax,%ax
> + │1330: mov %r15,%r10
> + │1333: cmp %r15,%r14
> +
> + annotate.show_nr_jumps::
> + Let's see a part of assembly code.
> +
> + │1382: movb $0x1,-0x270(%rbp)
> +
> + If use this, the number of branches branching to that address can be printed as below.

I think it'd be better to avoid using similar words in a row.
How about "number of branches jumping to that address" instead?

Thanks,
Namhyung


> +
> + │1 1382: movb $0x1,-0x270(%rbp)
> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 00:45:34

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 07/24] perf config: Document variables for 'help' section in man page

On Tue, Nov 17, 2015 at 10:53:27PM +0900, Taeung Song wrote:
> Explain 'help.format' and 'help.autocorrect' variables.
>
> Cc: Namhyung Kim <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 21 +++++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index bfbeb34..88e9b88 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -242,6 +242,27 @@ annotate.*::
>
> │1 1382: movb $0x1,-0x270(%rbp)
>
> +help.*::
> + help.format:: = man

What is this '= man' part? Is it for default value? It looks inconsistent anyway.


> + A format of manual page can be 'man', 'info', 'web' or 'html'.
> + 'man' is default.

I don't know we support other format of manual pages. Maybe asciidoc
does the job for us, but do we really care? At least 'info' seems broken..


> + help.autocorrect:: = 0
> + Automatically correct and execute mistyped commands after
> + waiting for the given number of deciseconds (0.1 sec).
> + Let's see a example. If a mistyped sub-command is executed like 'perf mistyped-command'

s/a example/an example/

> + and this option is 0, the output is as below.
> +
> + perf: 'mistyped-command' is not a perf-command. See 'perf --help'.
> +
> + Or if this option is more than 1, the output can be such as.
> +
> + WARNING: You called a perf program named 'mistyped-command', which does not exist.
> + Continuing under the assumption that you meant 'with-kcore'
> + in 0.1 seconds automatically...
> + Usage: perf-with-kcore <perf sub-command> <perf.data directory> [<sub-command options> [ -- <workload>]]
> + <perf sub-command> can be record, script, report or inject
> + or: perf-with-kcore fix_buildid_cache_permissions

I wasn't aware of this feature and it seems completely broken. If
it's a leftover from the git codebase, we'd better either to
disable/remove it or fix it.

Thanks,
Namhyung


> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 00:50:40

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 08/24] perf config: Document 'hist.percentage' variable in man page

On Tue, Nov 17, 2015 at 10:53:28PM +0900, Taeung Song wrote:
> Explain 'hist.percentage' variable.
>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>

Acked-by: Namhyung Kim <[email protected]>

One nitpick below..


> ---
> tools/perf/Documentation/perf-config.txt | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index 88e9b88..b166b81 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -263,6 +263,23 @@ help.*::
> <perf sub-command> can be record, script, report or inject
> or: perf-with-kcore fix_buildid_cache_permissions
>
> +hist.*::
> + hist.percentage::
> + This option control a way to calcurate overhead of filtered entries -

s/control a way/controls the way/, s/calcurate/calculate/

Thanks,
Namhyung


> + that means the value of this option is effective only if there's a
> + filter (by comm, dso or symbol name). Suppose a following example:
> +
> + Overhead Symbols
> + ........ .......
> + 33.33% foo
> + 33.33% bar
> + 33.33% baz
> +
> + This is an original overhead and we'll filter out the first 'foo'
> + entry. The value of 'relative' would increase the overhead of 'bar'
> + and 'baz' to 50.00% for each, while 'absolute' would show their
> + current overhead (33.33%).
> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 01:05:30

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 09/24] perf config: Document 'ui.show-headers' variable in man page

On Tue, Nov 17, 2015 at 10:53:29PM +0900, Taeung Song wrote:
> Explain 'ui.show-headers' variable.
>
> Cc: Namhyung Kim <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index b166b81..7d386d4 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -280,6 +280,11 @@ hist.*::
> and 'baz' to 50.00% for each, while 'absolute' would show their
> current overhead (33.33%).
>
> +ui.*::
> + ui.show-headers::
> + There're columns as header 'Overhead', 'Children', 'Shared Object', 'Symbol', 'self'.

How about this?

This option controls display of column headers (like 'Overhead'
and 'Symbol') in 'report' and 'top'.


> + If this option is false, they are hiden. This option is only applied to TUI.

s/hiden/hidden/

Thanks,
Namhyung


> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 02:51:09

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 10/24] perf config: Document variables for 'call-graph' section in man page

On Tue, Nov 17, 2015 at 10:53:30PM +0900, Taeung Song wrote:
> Explain 'call-graph' section and its variables.
>
> 'record-mode', 'dump-size', 'print-type', 'order',
> 'sort-key', 'threshold' and 'print-limit'.
>
> Cc: Namhyung Kim <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 65 ++++++++++++++++++++++++++++++++
> 1 file changed, 65 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index 7d386d4..dc659d6 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -285,6 +285,71 @@ ui.*::
> There're columns as header 'Overhead', 'Children', 'Shared Object', 'Symbol', 'self'.
> If this option is false, they are hiden. This option is only applied to TUI.
>
> +call-graph.*::
> + When sub-commands 'top' and 'report' work with -g/—-children
> + there're options in control of call-graph.
> +
> + call-graph.record-mode::
> + The record-mode can be 'fp' (frame pointer) and 'dwarf'.

Also 'lbr' can be used, but it only work for recent intel cpus.


> + The value of 'dwarf' is effective only if perf detect needed library
> + (libunwind or a recent version of libdw). Also it doesn't *require*
> + the dump-size option since it can use the default value of 8192 if
> + missing.

I think the last sentence can be omitted.


> +
> + call-graph.dump-size::
> + The size of stack to dump in order to do post-unwinding. Default is 8192 (byte).
> + When using dwarf into record-mode this option should have a value.

This contradicts the above, it'll use the default size if omitted.


> +
> + call-graph.print-type::
> + The print-types can be graph (graph absolute), fractal (graph relative), flat.
> + This option controls a way to show overhead for each callchain entry.
> + Suppose a following example.
> +
> + Overhead Symbols
> + ........ .......
> + 40.00% foo
> + |
> + --- foo
> + |
> + |--50.00%-- bar
> + | main
> + |
> + --50.00%-- baz
> + main

^
it needs one more whitespace


> +
> + This output is a 'fractal' format. The 'foo' came from 'bar' and 'baz' exactly
> + half and half so 'fractal' shows 50.00% for each
> + (meaning that it assumes 100% total overhead of 'foo').
> +
> + The 'graph' uses absolute overhead value of 'foo' as total so each of
> + 'bar' and 'baz' callchain will have 20.00% of overhead.
> +
> + call-graph.order::
> + This option controls print order of callchains. The default is
> + 'callee' which means callee is printed at top and then followed by its
> + caller and so on. The 'caller' prints it in reverse order.
> +
> + If this option is not set and report.children or top.children is
> + set to true (or the equivalent command line option is given),
> + the default value of this option is changed to 'caller' for the
> + execution of 'perf report' or 'perf top'. Other commands will
> + still default to 'callee'.
> +
> + call-graph.sort-key::
> + The callchains are merged if they contain same information.
> + The sort-key option determines a way to compare the callchains.
> + A value of 'sort-key' can be 'function' or 'address'.
> + The default is 'function'.
> +
> + call-graph.threshold::
> + When there're many callchains it'd print tons of lines. So perf omits
> + small callchains under a certain overhead (threshold) and this option
> + control the threashold. Default is 0.5 (%).

s/threashold/threshold/

Also it'd be better to mention that the overhead is calculated by
value depends on call-graph.print-type.


> +
> + call-graph.print-limit::
> + This is another way to control the number of callchains printed for a
> + single entry. Default is 0 which means no limitation.

This is a maximum number of lines of callchain printed for a single
histogram entry.

Thanks,
Namhyung


> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 03:01:10

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 11/24] perf config: Document variables for 'report' section in man page

On Tue, Nov 17, 2015 at 10:53:31PM +0900, Taeung Song wrote:
> Explain 'report' section's variables.
>
> 'percent-limit', 'queue-size' and 'children'.
>
> Cc: Namhyung Kim <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index dc659d6..b9f89dd 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -350,6 +350,23 @@ call-graph.*::
> This is another way to control the number of callchains printed for a
> single entry. Default is 0 which means no limitation.
>
> +report.*::
> + report.percent-limit::
> + This one is mostly same as call-graph.threshold but works for
> + histogram entries. Entries have overhead lower than this percentage
> + will not be printed. Default is 0.
> + If percent-limit is 70, the output which has percentages of
> + each overhead above 70% can be printed.

70% is an unrealistric example IMHO. :) How about this?

If percent-limit is 10, entries which have more than 10% of overhead
will be printed only.

> +
> + report.queue-size::
> + option to setup the maximum allocation size for session's
> + ordered events queue, if not set there's no default limit.

This option is to setup the maximum allocation size of internal
event queue for ordering events. Default is 0, meaning no limit.


> +
> + report.children::
> + The children means that functions called from another function.
> + If the option is true, accumulate callchain of children and show total overhead.

If this option is true, perf report cumulates callchains of children
and show (accumulated) total overhead as well as self overhead.

Thanks,
Namhyung


> + Please refer to the perf-report manual. The default is true.
> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 03:04:14

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 12/24] perf config: Document 'top.chidren' variable in man page

On Tue, Nov 17, 2015 at 10:53:32PM +0900, Taeung Song wrote:
> Explain 'top.children' variable.
>
> Cc: Namhyung Kim <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index b9f89dd..344feb8 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -367,6 +367,12 @@ report.*::
> If the option is true, accumulate callchain of children and show total overhead.
> Please refer to the perf-report manual. The default is true.
>
> +top.*::
> + top.children::
> + This option means same as report.children. So it is true,
> + the output of 'top' is rearranged by each overhead into children group.

This option means same as report.children. So if it's true,
the output of 'top' command will have 'Children' overhead column
as well as 'Self' overhead column by default.

Thanks,
Namhyung


> + The default is true.
> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 04:58:25

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 13/24] perf config: Document 'man.viewer' variable in man page

On Tue, Nov 17, 2015 at 10:53:33PM +0900, Taeung Song wrote:
> Explain 'man.viewer' variable.
>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index 344feb8..ea1d3e1 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -373,6 +373,11 @@ top.*::
> the output of 'top' is rearranged by each overhead into children group.
> The default is true.
>
> +man.*::
> + man.viewer::
> + This option can assign a manual tool with which a subcommand 'help' work.
> + it can used as 'man', 'woman', 'konqueror'. Default value is 'man'.

This option can assign a tool to view manual pages when 'help'
subcommand was invoked. Supported tools are 'man', 'woman'
(with emacs client), and 'konqueror'. Default is 'man'.

It seems one can also add new man viewer tool using 'man.<tool>.cmd'
or use different path using 'man.<tool>.path' config option.

Thanks,
Namhyung


> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 05:05:10

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 14/24] perf config: Document 'pager.<subcommand>' variables in man page

On Tue, Nov 17, 2015 at 10:53:34PM +0900, Taeung Song wrote:
> Explain 'pager.<subcommand>' variables.
>
> Cc: Namhyung Kim <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index ea1d3e1..8e7ffde 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -378,6 +378,11 @@ man.*::
> This option can assign a manual tool with which a subcommand 'help' work.
> it can used as 'man', 'woman', 'konqueror'. Default value is 'man'.
>
> +pager.*::
> + pager.<subcommand>::
> + When a subcommand work as stdio instead of TUI, use pager with it.
> + Default value is 'true'.

When the subcommand is run on stdio, determine whether it uses
pager or not based on this value. Default is 'unspecified'.

Thanks,
Namhyung


> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 05:08:30

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 15/24] perf config: Document 'kmem.default' variable in man page

On Tue, Nov 17, 2015 at 10:53:35PM +0900, Taeung Song wrote:
> Explain 'kmem.default' variable.
>
> Cc: Namhyung Kim <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index 8e7ffde..95255a0 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -383,6 +383,12 @@ pager.*::
> When a subcommand work as stdio instead of TUI, use pager with it.
> Default value is 'true'.
>
> +kmem.*::
> + kmem.default::
> + This option can decide which allocator is analyzed between 'slab' and 'page'
> + without using options '--slab' and '--page'.
> + Default value is 'slab'.

This option decides which allocator is to be analyzed if neither
'--slab' nor '--page' option is used. Default is 'slab'.

Thanks,
Namhyung


> +
> SEE ALSO
> --------
> linkperf:perf[1]
> --
> 1.9.1
>

2015-11-18 05:11:27

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 16/24] perf config: Add '--system' and '--user' options to select which config file is used

On Tue, Nov 17, 2015 at 10:53:36PM +0900, Taeung Song wrote:
> The file-options '--system' means $(sysconfdir)/perfconfig and
> '--user' means $HOME/.perfconfig. If file-option isn't used,
> both system and user config file is read.
> The syntax examples are like below.
>
> perf config [<file-option>] [options]
>
> a specific config file.
> # perf config --user | --system
> or
> both user and system config file.
> # perf config
>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>

Acked-by: Namhyung Kim <[email protected]>

Thanks,
Namhyung


> ---
> tools/perf/Documentation/perf-config.txt | 14 +++++++++++++-
> tools/perf/builtin-config.c | 18 +++++++++++++++++-
> tools/perf/util/cache.h | 3 +++
> tools/perf/util/config.c | 4 ++--
> 4 files changed, 35 insertions(+), 4 deletions(-)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index 95255a0..f556672 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -8,7 +8,7 @@ perf-config - Get and set variables in a configuration file.
> SYNOPSIS
> --------
> [verse]
> -'perf config' -l | --list
> +'perf config' [<file-option>] -l | --list
>
> DESCRIPTION
> -----------
> @@ -21,6 +21,14 @@ OPTIONS
> --list::
> Show current config variables, name and value, for all sections.
>
> +--user::
> + For writing and reading options: write to user
> + '$HOME/.perfconfig' file or read it.
> +
> +--system::
> + For writing and reading options: write to system-wide
> + '$(sysconfdir)/perfconfig' or read it.
> +
> CONFIGURATION FILE
> ------------------
>
> @@ -30,6 +38,10 @@ The '$HOME/.perfconfig' file is used to store a per-user configuration.
> The file '$(sysconfdir)/perfconfig' can be used to
> store a system-wide default configuration.
>
> +When reading or writing, the values are read from the system and user
> +configuration files by default, and options '--system' and '--user'
> +can be used to tell the command to read from or write to only that location.
> +
> Syntax
> ~~~~~~
>
> diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
> index 427ea7a..e0f8b41 100644
> --- a/tools/perf/builtin-config.c
> +++ b/tools/perf/builtin-config.c
> @@ -13,8 +13,10 @@
> #include "util/util.h"
> #include "util/debug.h"
>
> +static bool use_system_config, use_user_config;
> +
> static const char * const config_usage[] = {
> - "perf config [options]",
> + "perf config [<file-option>] [options]",
> NULL
> };
>
> @@ -25,6 +27,8 @@ enum actions {
> static struct option config_options[] = {
> OPT_SET_UINT('l', "list", &actions,
> "show current config variables", ACTION_LIST),
> + OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
> + OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
> OPT_END()
> };
>
> @@ -46,6 +50,18 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
> argc = parse_options(argc, argv, config_options, config_usage,
> PARSE_OPT_STOP_AT_NON_OPTION);
>
> + if (use_system_config && use_user_config) {
> + pr_err("Error: only one config file at a time\n");
> + parse_options_usage(config_usage, config_options, "user", 0);
> + parse_options_usage(NULL, config_options, "system", 0);
> + return -1;
> + }
> +
> + if (use_system_config)
> + config_exclusive_filename = perf_etc_perfconfig();
> + else if (use_user_config)
> + config_exclusive_filename = mkpath("%s/.perfconfig", getenv("HOME"));
> +
> switch (actions) {
> case ACTION_LIST:
> if (argc) {
> diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
> index c861373..d1eb75f 100644
> --- a/tools/perf/util/cache.h
> +++ b/tools/perf/util/cache.h
> @@ -19,6 +19,8 @@
> #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
> #define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
>
> +extern const char *config_exclusive_filename;
> +
> typedef int (*config_fn_t)(const char *, const char *, void *);
> extern int perf_default_config(const char *, const char *, void *);
> extern int perf_config(config_fn_t fn, void *);
> @@ -27,6 +29,7 @@ extern u64 perf_config_u64(const char *, const char *);
> extern int perf_config_bool(const char *, const char *);
> extern int config_error_nonbool(const char *);
> extern const char *perf_config_dirname(const char *, const char *);
> +extern const char *perf_etc_perfconfig(void);
>
> /* pager.c */
> extern void setup_pager(void);
> diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
> index 2e452ac..55ef373 100644
> --- a/tools/perf/util/config.c
> +++ b/tools/perf/util/config.c
> @@ -26,7 +26,7 @@ static const char *config_file_name;
> static int config_linenr;
> static int config_file_eof;
>
> -static const char *config_exclusive_filename;
> +const char *config_exclusive_filename;
>
> static int get_next_char(void)
> {
> @@ -434,7 +434,7 @@ static int perf_config_from_file(config_fn_t fn, const char *filename, void *dat
> return ret;
> }
>
> -static const char *perf_etc_perfconfig(void)
> +const char *perf_etc_perfconfig(void)
> {
> static const char *system_wide;
> if (!system_wide)
> --
> 1.9.1
>

2015-11-18 05:15:29

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 17/24] perf config: Collect configs to handle config variables

On Tue, Nov 17, 2015 at 10:53:37PM +0900, Taeung Song wrote:
> Collecting configs into list because of two reason.
>
> First of all, if there are same variables both user
> and system config file, they all will be printed
> when 'list' command work. But if config variables are
> duplicated, user config variables should only be printed
> because it has priority.
>
> Lastly, list into which configs is collected
> will be required to keep and handle config variables
> and values in the near furture. For example,
> getting or setting functionality.
>
> And change show_config() function.
> Old show_config() worked depending on perf_config().
> New show_config() work using collected configs list.
>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>

Acked-by: Namhyung Kim <[email protected]>

Thanks,
Namhyung


> ---
> tools/perf/builtin-config.c | 150 ++++++++++++++++++++++++++++++++++++++++++--
> tools/perf/util/cache.h | 13 ++++
> 2 files changed, 158 insertions(+), 5 deletions(-)
>
> diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
> index e0f8b41..185aa5e 100644
> --- a/tools/perf/builtin-config.c
> +++ b/tools/perf/builtin-config.c
> @@ -32,13 +32,148 @@ static struct option config_options[] = {
> OPT_END()
> };
>
> -static int show_config(const char *key, const char *value,
> - void *cb __maybe_unused)
> +static struct config_section *find_section(struct list_head *sections,
> + const char *section_name)
> {
> + struct config_section *section;
> +
> + list_for_each_entry(section, sections, list)
> + if (!strcmp(section->name, section_name))
> + return section;
> +
> + return NULL;
> +}
> +
> +static struct config_element *find_element(const char *name,
> + struct config_section *section)
> +{
> + struct config_element *element;
> +
> + list_for_each_entry(element, &section->element_head, list)
> + if (!strcmp(element->name, name))
> + return element;
> +
> + return NULL;
> +}
> +
> +static void find_config(struct list_head *sections,
> + struct config_section **section,
> + struct config_element **element,
> + const char *section_name, const char *name)
> +{
> + *section = find_section(sections, section_name);
> +
> + if (*section != NULL)
> + *element = find_element(name, *section);
> + else
> + *element = NULL;
> +}
> +
> +static struct config_section *init_section(const char *section_name)
> +{
> + struct config_section *section;
> +
> + section = zalloc(sizeof(*section));
> + if (!section)
> + return NULL;
> +
> + INIT_LIST_HEAD(&section->element_head);
> + section->name = strdup(section_name);
> + if (!section->name) {
> + pr_err("%s: strdup failed\n", __func__);
> + free(section);
> + return NULL;
> + }
> +
> + return section;
> +}
> +
> +static int add_element(struct list_head *head,
> + const char *name, const char *value)
> +{
> + struct config_element *element;
> +
> + element = zalloc(sizeof(*element));
> + if (!element)
> + return -1;
> +
> + element->name = strdup(name);
> + if (!element->name) {
> + pr_err("%s: strdup failed\n", __func__);
> + free(element);
> + return -1;
> + }
> if (value)
> - printf("%s=%s\n", key, value);
> + element->value = (char *)value;
> else
> - printf("%s\n", key);
> + element->value = NULL;
> +
> + list_add_tail(&element->list, head);
> + return 0;
> +}
> +
> +static int collect_current_config(const char *var, const char *value,
> + void *spec_sections)
> +{
> + int ret = -1;
> + char *ptr, *key;
> + char *section_name, *name;
> + struct config_section *section = NULL;
> + struct config_element *element = NULL;
> + struct list_head *sections = (struct list_head *)spec_sections;
> +
> + key = ptr = strdup(var);
> + if (!key) {
> + pr_err("%s: strdup failed\n", __func__);
> + return -1;
> + }
> +
> + section_name = strsep(&ptr, ".");
> + name = ptr;
> + if (name == NULL || value == NULL)
> + goto out_err;
> +
> + find_config(sections, &section, &element, section_name, name);
> +
> + if (!section) {
> + section = init_section(section_name);
> + if (!section)
> + goto out_err;
> + list_add_tail(&section->list, sections);
> + }
> +
> + value = strdup(value);
> + if (!value) {
> + pr_err("%s: strdup failed\n", __func__);
> + goto out_err;
> + }
> +
> + if (!element)
> + add_element(&section->element_head, name, value);
> + else {
> + free(element->value);
> + element->value = (char *)value;
> + }
> +
> + ret = 0;
> +out_err:
> + free(key);
> + return ret;
> +}
> +
> +static int show_config(struct list_head *sections)
> +{
> + struct config_section *section;
> + struct config_element *element;
> +
> + if (list_empty(sections))
> + return -1;
> + list_for_each_entry(section, sections, list) {
> + list_for_each_entry(element, &section->element_head, list) {
> + printf("%s.%s=%s\n", section->name,
> + element->name, element->value);
> + }
> + }
>
> return 0;
> }
> @@ -46,6 +181,7 @@ static int show_config(const char *key, const char *value,
> int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
> {
> int ret = 0;
> + struct list_head sections;
>
> argc = parse_options(argc, argv, config_options, config_usage,
> PARSE_OPT_STOP_AT_NON_OPTION);
> @@ -57,18 +193,22 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
> return -1;
> }
>
> + INIT_LIST_HEAD(&sections);
> +
> if (use_system_config)
> config_exclusive_filename = perf_etc_perfconfig();
> else if (use_user_config)
> config_exclusive_filename = mkpath("%s/.perfconfig", getenv("HOME"));
>
> + perf_config(collect_current_config, &sections);
> +
> switch (actions) {
> case ACTION_LIST:
> if (argc) {
> pr_err("Error: takes no arguments\n");
> parse_options_usage(config_usage, config_options, "l", 1);
> } else {
> - ret = perf_config(show_config, NULL);
> + ret = show_config(&sections);
> if (ret < 0)
> pr_err("Nothing configured, "
> "please check your ~/.perfconfig file\n");
> diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
> index d1eb75f..e503371 100644
> --- a/tools/perf/util/cache.h
> +++ b/tools/perf/util/cache.h
> @@ -1,6 +1,7 @@
> #ifndef __PERF_CACHE_H
> #define __PERF_CACHE_H
>
> +#include <linux/list.h>
> #include <stdbool.h>
> #include "util.h"
> #include "strbuf.h"
> @@ -19,6 +20,18 @@
> #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
> #define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
>
> +struct config_element {
> + char *name;
> + char *value;
> + struct list_head list;
> +};
> +
> +struct config_section {
> + char *name;
> + struct list_head element_head;
> + struct list_head list;
> +};
> +
> extern const char *config_exclusive_filename;
>
> typedef int (*config_fn_t)(const char *, const char *, void *);
> --
> 1.9.1
>

2015-11-19 19:24:27

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH v11 02/24] perf tools: Add perf-config document

Em Wed, Nov 18, 2015 at 08:13:13AM +0900, Namhyung Kim escreveu:
> On Tue, Nov 17, 2015 at 10:53:22PM +0900, Taeung Song wrote:
> > Add perf-config document to describe the perf configuration
> > and a subcommand 'list'.
> >
> > Cc: Jiri Olsa <[email protected]>
> > Signed-off-by: Taeung Song <[email protected]>
>
> Acked-by: Namhyung Kim <[email protected]>

Taeung, please check this:

[acme@zoo linux]$ rpm -q asciidoc
asciidoc-8.6.8-6.fc21.noarch

I applied the first patch, continue your work from my perf/core branch.

INSTALL perf_completion-script
INSTALL tests
ASCIIDOC /tmp/build/perf/perf-kmem.xml
ASCIIDOC /tmp/build/perf/perf-trace.xml
ASCIIDOC /tmp/build/perf/perf-data.xml
ASCIIDOC /tmp/build/perf/perf-buildid-cache.xml
ASCIIDOC /tmp/build/perf/perf-list.xml
ASCIIDOC /tmp/build/perf/perf-help.xml
ASCIIDOC /tmp/build/perf/perf-script.xml
ASCIIDOC /tmp/build/perf/perf-lock.xml
ASCIIDOC /tmp/build/perf/perf-archive.xml
ASCIIDOC /tmp/build/perf/perf-probe.xml
ASCIIDOC /tmp/build/perf/perf-config.xml
ASCIIDOC /tmp/build/perf/perf-bench.xml
ASCIIDOC /tmp/build/perf/perf-evlist.xml
asciidoc: WARNING: perf-config.txt: line 59: missing style: [paradef-literal]: colors
asciidoc: WARNING: perf-config.txt: line 69: missing style: [paradef-literal]: tui
asciidoc: WARNING: perf-config.txt: line 75: missing style: [paradef-literal]: buildid
asciidoc: WARNING: perf-config.txt: line 79: missing style: [paradef-literal]: annotate
asciidoc: WARNING: perf-config.txt: line 86: missing style: [paradef-literal]: help
asciidoc: WARNING: perf-config.txt: line 91: missing style: [paradef-literal]: ui
asciidoc: WARNING: perf-config.txt: line 94: missing style: [paradef-literal]: call-graph
ASCIIDOC /tmp/build/perf/perf-sched.xml

2015-11-22 10:10:34

by Taeung Song

[permalink] [raw]
Subject: Re: [PATCH v11 02/24] perf tools: Add perf-config document

Hi, Arnaldo, Namhyung

I left out indentation for config example.
I fixed the bugs and I resent patch mail.

Thanks,
Taeung
> On Nov 20, 2015, at 4:24 AM, Arnaldo Carvalho de Melo <[email protected]> wrote:
>
> Em Wed, Nov 18, 2015 at 08:13:13AM +0900, Namhyung Kim escreveu:
>> On Tue, Nov 17, 2015 at 10:53:22PM +0900, Taeung Song wrote:
>>> Add perf-config document to describe the perf configuration
>>> and a subcommand 'list'.
>>>
>>> Cc: Jiri Olsa <[email protected]>
>>> Signed-off-by: Taeung Song <[email protected]>
>>
>> Acked-by: Namhyung Kim <[email protected]>
>
> Taeung, please check this:
>
> [acme@zoo linux]$ rpm -q asciidoc
> asciidoc-8.6.8-6.fc21.noarch
>
> I applied the first patch, continue your work from my perf/core branch.
>
> INSTALL perf_completion-script
> INSTALL tests
> ASCIIDOC /tmp/build/perf/perf-kmem.xml
> ASCIIDOC /tmp/build/perf/perf-trace.xml
> ASCIIDOC /tmp/build/perf/perf-data.xml
> ASCIIDOC /tmp/build/perf/perf-buildid-cache.xml
> ASCIIDOC /tmp/build/perf/perf-list.xml
> ASCIIDOC /tmp/build/perf/perf-help.xml
> ASCIIDOC /tmp/build/perf/perf-script.xml
> ASCIIDOC /tmp/build/perf/perf-lock.xml
> ASCIIDOC /tmp/build/perf/perf-archive.xml
> ASCIIDOC /tmp/build/perf/perf-probe.xml
> ASCIIDOC /tmp/build/perf/perf-config.xml
> ASCIIDOC /tmp/build/perf/perf-bench.xml
> ASCIIDOC /tmp/build/perf/perf-evlist.xml
> asciidoc: WARNING: perf-config.txt: line 59: missing style: [paradef-literal]: colors
> asciidoc: WARNING: perf-config.txt: line 69: missing style: [paradef-literal]: tui
> asciidoc: WARNING: perf-config.txt: line 75: missing style: [paradef-literal]: buildid
> asciidoc: WARNING: perf-config.txt: line 79: missing style: [paradef-literal]: annotate
> asciidoc: WARNING: perf-config.txt: line 86: missing style: [paradef-literal]: help
> asciidoc: WARNING: perf-config.txt: line 91: missing style: [paradef-literal]: ui
> asciidoc: WARNING: perf-config.txt: line 94: missing style: [paradef-literal]: call-graph
> ASCIIDOC /tmp/build/perf/perf-sched.xml
>

2015-11-22 10:12:03

by Taeung Song

[permalink] [raw]
Subject: [PATCH v11 RESEND 02/24] perf tools: Add perf-config document

Add perf-config document to describe the perf configuration
and a subcommand 'list’.

Cc: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Signed-off-by: Taeung Song <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 103 +++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
create mode 100644 tools/perf/Documentation/perf-config.txt

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
new file mode 100644
index 0000000..b9ca1e3
--- /dev/null
+++ b/tools/perf/Documentation/perf-config.txt
@@ -0,0 +1,103 @@
+perf-config(1)
+==============
+
+NAME
+----
+perf-config - Get and set variables in a configuration file.
+
+SYNOPSIS
+--------
+[verse]
+'perf config' -l | --list
+
+DESCRIPTION
+-----------
+You can manage variables in a configuration file with this command.
+
+OPTIONS
+-------
+
+-l::
+--list::
+ Show current config variables, name and value, for all sections.
+
+CONFIGURATION FILE
+------------------
+
+The perf configuration file contains many variables to change various
+aspects of each of its tools, including output, disk usage, etc.
+The '$HOME/.perfconfig' file is used to store a per-user configuration.
+The file '$(sysconfdir)/perfconfig' can be used to
+store a system-wide default configuration.
+
+Syntax
+~~~~~~
+
+The file consist of sections. A section starts with its name
+surrounded by square brackets and continues till the next section
+begins. Each variable must be in a section, and have the form
+'name = value', for example:
+
+ [section]
+ name1 = value1
+ name2 = value2
+
+Section names are case sensitive and can contain any characters except
+newline (double quote `"` and backslash have to be escaped as `\"` and `\\`,
+respectively). Section headers can't span multiple lines.
+
+Example
+~~~~~~~
+
+Given a $HOME/.perfconfig like this:
+
+#
+# This is the config file, and
+# a '#' and ';' character indicates a comment
+#
+
+ [colors]
+ # Color variables
+ top = red, default
+ medium = green, default
+ normal = lightgray, default
+ selected = white, lightgray
+ code = blue, default
+ addr = magenta, default
+ root = white, blue
+
+ [tui]
+ # Defaults if linked with libslang
+ report = on
+ annotate = on
+ top = on
+
+ [buildid]
+ # Default, disable using /dev/null
+ dir = ~/.debug
+
+ [annotate]
+ # Defaults
+ hide_src_code = false
+ use_offset = true
+ jump_arrows = true
+ show_nr_jumps = false
+
+ [help]
+ # Format can be man, info, web or html
+ format = man
+ autocorrect = 0
+
+ [ui]
+ show-headers = true
+
+ [call-graph]
+ # fp (framepointer), dwarf
+ record-mode = fp
+ print-type = graph
+ order = caller
+ sort-key = function
+
+SEE ALSO
+--------
+linkperf:perf[1]
--
1.9.1-

2015-11-23 14:17:56

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH v11 RESEND 02/24] perf tools: Add perf-config document

Em Sun, Nov 22, 2015 at 07:11:56PM +0900, Taeung Song escreveu:
> Add perf-config document to describe the perf configuration
> and a subcommand 'list’.

Worked this time, applied, will continue processing the other patches
soon.

- Arnaldo

> Cc: Namhyung Kim <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Signed-off-by: Taeung Song <[email protected]>
> ---
> tools/perf/Documentation/perf-config.txt | 103 +++++++++++++++++++++++++++++++
> 1 file changed, 103 insertions(+)
> create mode 100644 tools/perf/Documentation/perf-config.txt
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> new file mode 100644
> index 0000000..b9ca1e3
> --- /dev/null
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -0,0 +1,103 @@
> +perf-config(1)
> +==============
> +
> +NAME
> +----
> +perf-config - Get and set variables in a configuration file.
> +
> +SYNOPSIS
> +--------
> +[verse]
> +'perf config' -l | --list
> +
> +DESCRIPTION
> +-----------
> +You can manage variables in a configuration file with this command.
> +
> +OPTIONS
> +-------
> +
> +-l::
> +--list::
> + Show current config variables, name and value, for all sections.
> +
> +CONFIGURATION FILE
> +------------------
> +
> +The perf configuration file contains many variables to change various
> +aspects of each of its tools, including output, disk usage, etc.
> +The '$HOME/.perfconfig' file is used to store a per-user configuration.
> +The file '$(sysconfdir)/perfconfig' can be used to
> +store a system-wide default configuration.
> +
> +Syntax
> +~~~~~~
> +
> +The file consist of sections. A section starts with its name
> +surrounded by square brackets and continues till the next section
> +begins. Each variable must be in a section, and have the form
> +'name = value', for example:
> +
> + [section]
> + name1 = value1
> + name2 = value2
> +
> +Section names are case sensitive and can contain any characters except
> +newline (double quote `"` and backslash have to be escaped as `\"` and `\\`,
> +respectively). Section headers can't span multiple lines.
> +
> +Example
> +~~~~~~~
> +
> +Given a $HOME/.perfconfig like this:
> +
> +#
> +# This is the config file, and
> +# a '#' and ';' character indicates a comment
> +#
> +
> + [colors]
> + # Color variables
> + top = red, default
> + medium = green, default
> + normal = lightgray, default
> + selected = white, lightgray
> + code = blue, default
> + addr = magenta, default
> + root = white, blue
> +
> + [tui]
> + # Defaults if linked with libslang
> + report = on
> + annotate = on
> + top = on
> +
> + [buildid]
> + # Default, disable using /dev/null
> + dir = ~/.debug
> +
> + [annotate]
> + # Defaults
> + hide_src_code = false
> + use_offset = true
> + jump_arrows = true
> + show_nr_jumps = false
> +
> + [help]
> + # Format can be man, info, web or html
> + format = man
> + autocorrect = 0
> +
> + [ui]
> + show-headers = true
> +
> + [call-graph]
> + # fp (framepointer), dwarf
> + record-mode = fp
> + print-type = graph
> + order = caller
> + sort-key = function
> +
> +SEE ALSO
> +--------
> +linkperf:perf[1]
> --
> 1.9.1

Subject: [tip:perf/core] perf tools: Add 'perf config' command

Commit-ID: 30862f2c5725c46afcfab5af710fdf5163bf0f81
Gitweb: http://git.kernel.org/tip/30862f2c5725c46afcfab5af710fdf5163bf0f81
Author: Taeung Song <[email protected]>
AuthorDate: Tue, 17 Nov 2015 22:53:21 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 23 Nov 2015 18:31:24 -0300

perf tools: Add 'perf config' command

The perf configuration file contains many variables to change various
aspects of each of its tools, including output, disk usage, etc.

But looking at the state of configuration is difficult and there's no
documentation about config variables except for the variables in
perfconfig.example exist.

So this patch adds a 'perf-config' command with a '--list' option.

perf config [options]

display current perf config variables.
# perf config -l | --list

Signed-off-by: Taeung Song <[email protected]>
Acked-by: Namhyung Kim <[email protected]>
Cc: Jiri Olsa <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Build | 1 +
tools/perf/builtin-config.c | 66 +++++++++++++++++++++++++++++++++++++++++++++
tools/perf/builtin.h | 1 +
tools/perf/command-list.txt | 1 +
tools/perf/perf.c | 1 +
5 files changed, 70 insertions(+)

diff --git a/tools/perf/Build b/tools/perf/Build
index 7223745..2c7aaf2 100644
--- a/tools/perf/Build
+++ b/tools/perf/Build
@@ -1,5 +1,6 @@
perf-y += builtin-bench.o
perf-y += builtin-annotate.o
+perf-y += builtin-config.o
perf-y += builtin-diff.o
perf-y += builtin-evlist.o
perf-y += builtin-help.o
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
new file mode 100644
index 0000000..427ea7a
--- /dev/null
+++ b/tools/perf/builtin-config.c
@@ -0,0 +1,66 @@
+/*
+ * builtin-config.c
+ *
+ * Copyright (C) 2015, Taeung Song <[email protected]>
+ *
+ */
+#include "builtin.h"
+
+#include "perf.h"
+
+#include "util/cache.h"
+#include "util/parse-options.h"
+#include "util/util.h"
+#include "util/debug.h"
+
+static const char * const config_usage[] = {
+ "perf config [options]",
+ NULL
+};
+
+enum actions {
+ ACTION_LIST = 1
+} actions;
+
+static struct option config_options[] = {
+ OPT_SET_UINT('l', "list", &actions,
+ "show current config variables", ACTION_LIST),
+ OPT_END()
+};
+
+static int show_config(const char *key, const char *value,
+ void *cb __maybe_unused)
+{
+ if (value)
+ printf("%s=%s\n", key, value);
+ else
+ printf("%s\n", key);
+
+ return 0;
+}
+
+int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
+{
+ int ret = 0;
+
+ argc = parse_options(argc, argv, config_options, config_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+
+ switch (actions) {
+ case ACTION_LIST:
+ if (argc) {
+ pr_err("Error: takes no arguments\n");
+ parse_options_usage(config_usage, config_options, "l", 1);
+ } else {
+ ret = perf_config(show_config, NULL);
+ if (ret < 0)
+ pr_err("Nothing configured, "
+ "please check your ~/.perfconfig file\n");
+ }
+ break;
+ default:
+ usage_with_options(config_usage, config_options);
+ }
+
+ return ret;
+}
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 3688ad2..3f871b5 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -17,6 +17,7 @@ extern int cmd_annotate(int argc, const char **argv, const char *prefix);
extern int cmd_bench(int argc, const char **argv, const char *prefix);
extern int cmd_buildid_cache(int argc, const char **argv, const char *prefix);
extern int cmd_buildid_list(int argc, const char **argv, const char *prefix);
+extern int cmd_config(int argc, const char **argv, const char *prefix);
extern int cmd_diff(int argc, const char **argv, const char *prefix);
extern int cmd_evlist(int argc, const char **argv, const char *prefix);
extern int cmd_help(int argc, const char **argv, const char *prefix);
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index 00fcaf8..acc3ea7 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -9,6 +9,7 @@ perf-buildid-cache mainporcelain common
perf-buildid-list mainporcelain common
perf-data mainporcelain common
perf-diff mainporcelain common
+perf-config mainporcelain common
perf-evlist mainporcelain common
perf-inject mainporcelain common
perf-kmem mainporcelain common
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 3d4c7c0..4bee53c 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -39,6 +39,7 @@ struct cmd_struct {
static struct cmd_struct commands[] = {
{ "buildid-cache", cmd_buildid_cache, 0 },
{ "buildid-list", cmd_buildid_list, 0 },
+ { "config", cmd_config, 0 },
{ "diff", cmd_diff, 0 },
{ "evlist", cmd_evlist, 0 },
{ "help", cmd_help, 0 },

Subject: [tip:perf/core] perf config: Add initial man page

Commit-ID: 7d6852432acb3b09fc3ec45dd65421d34eebe3b5
Gitweb: http://git.kernel.org/tip/7d6852432acb3b09fc3ec45dd65421d34eebe3b5
Author: Taeung Song <[email protected]>
AuthorDate: Sun, 22 Nov 2015 19:11:56 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 23 Nov 2015 18:31:25 -0300

perf config: Add initial man page

Add perf-config document to describe the perf configuration and a
'list’ subcommand.

Signed-off-by: Taeung Song <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Documentation/perf-config.txt | 103 +++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
new file mode 100644
index 0000000..b9ca1e3
--- /dev/null
+++ b/tools/perf/Documentation/perf-config.txt
@@ -0,0 +1,103 @@
+perf-config(1)
+==============
+
+NAME
+----
+perf-config - Get and set variables in a configuration file.
+
+SYNOPSIS
+--------
+[verse]
+'perf config' -l | --list
+
+DESCRIPTION
+-----------
+You can manage variables in a configuration file with this command.
+
+OPTIONS
+-------
+
+-l::
+--list::
+ Show current config variables, name and value, for all sections.
+
+CONFIGURATION FILE
+------------------
+
+The perf configuration file contains many variables to change various
+aspects of each of its tools, including output, disk usage, etc.
+The '$HOME/.perfconfig' file is used to store a per-user configuration.
+The file '$(sysconfdir)/perfconfig' can be used to
+store a system-wide default configuration.
+
+Syntax
+~~~~~~
+
+The file consist of sections. A section starts with its name
+surrounded by square brackets and continues till the next section
+begins. Each variable must be in a section, and have the form
+'name = value', for example:
+
+ [section]
+ name1 = value1
+ name2 = value2
+
+Section names are case sensitive and can contain any characters except
+newline (double quote `"` and backslash have to be escaped as `\"` and `\\`,
+respectively). Section headers can't span multiple lines.
+
+Example
+~~~~~~~
+
+Given a $HOME/.perfconfig like this:
+
+#
+# This is the config file, and
+# a '#' and ';' character indicates a comment
+#
+
+ [colors]
+ # Color variables
+ top = red, default
+ medium = green, default
+ normal = lightgray, default
+ selected = white, lightgray
+ code = blue, default
+ addr = magenta, default
+ root = white, blue
+
+ [tui]
+ # Defaults if linked with libslang
+ report = on
+ annotate = on
+ top = on
+
+ [buildid]
+ # Default, disable using /dev/null
+ dir = ~/.debug
+
+ [annotate]
+ # Defaults
+ hide_src_code = false
+ use_offset = true
+ jump_arrows = true
+ show_nr_jumps = false
+
+ [help]
+ # Format can be man, info, web or html
+ format = man
+ autocorrect = 0
+
+ [ui]
+ show-headers = true
+
+ [call-graph]
+ # fp (framepointer), dwarf
+ record-mode = fp
+ print-type = graph
+ order = caller
+ sort-key = function
+
+SEE ALSO
+--------
+linkperf:perf[1]

2015-11-30 01:42:09

by Taeung Song

[permalink] [raw]
Subject: Re: [PATCH v11 10/24] perf config: Document variables for 'call-graph' section in man page

Hi, Namhyung


> On Nov 18, 2015, at 11:51 AM, Namhyung Kim <[email protected]> wrote:
>
> On Tue, Nov 17, 2015 at 10:53:30PM +0900, Taeung Song wrote:
>> Explain 'call-graph' section and its variables.
>>
>> 'record-mode', 'dump-size', 'print-type', 'order',
>> 'sort-key', 'threshold' and 'print-limit'.
>>
>> Cc: Namhyung Kim <[email protected]>
>> Cc: Jiri Olsa <[email protected]>
>> Signed-off-by: Taeung Song <[email protected]>
>> ---
>> tools/perf/Documentation/perf-config.txt | 65 ++++++++++++++++++++++++++++++++
>> 1 file changed, 65 insertions(+)
>>
>> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
>> index 7d386d4..dc659d6 100644
>> --- a/tools/perf/Documentation/perf-config.txt
>> +++ b/tools/perf/Documentation/perf-config.txt
>> @@ -285,6 +285,71 @@ ui.*::
>> There're columns as header 'Overhead', 'Children', 'Shared Object', 'Symbol', 'self'.
>> If this option is false, they are hiden. This option is only applied to TUI.
>>
>> +call-graph.*::
>> + When sub-commands 'top' and 'report' work with -g/—-children
>> + there're options in control of call-graph.
>> +
>> + call-graph.record-mode::
>> + The record-mode can be 'fp' (frame pointer) and 'dwarf'.
>
> Also 'lbr' can be used, but it only work for recent intel cpus.
>
>
>> + The value of 'dwarf' is effective only if perf detect needed library
>> + (libunwind or a recent version of libdw). Also it doesn't *require*
>> + the dump-size option since it can use the default value of 8192 if
>> + missing.
>
> I think the last sentence can be omitted.
>
>
>> +
>> + call-graph.dump-size::
>> + The size of stack to dump in order to do post-unwinding. Default is 8192 (byte).
>> + When using dwarf into record-mode this option should have a value.
>
> This contradicts the above, it'll use the default size if omitted.
>
>
>> +
>> + call-graph.print-type::
>> + The print-types can be graph (graph absolute), fractal (graph relative), flat.
>> + This option controls a way to show overhead for each callchain entry.
>> + Suppose a following example.
>> +
>> + Overhead Symbols
>> + ........ .......
>> + 40.00% foo
>> + |
>> + --- foo
>> + |
>> + |--50.00%-- bar
>> + | main
>> + |
>> + --50.00%-- baz
>> + main
>
> ^
> it needs one more whitespace
>

I checked this patch file and whitespace and tab characters on it.
But I think the lacking whitespace because of mail client.
After 'make install’ I checked it but there is no lack of whitespace.
Are there different problems that I missed ?


Thanks,
Taeung

>
>> +
>> + This output is a 'fractal' format. The 'foo' came from 'bar' and 'baz' exactly
>> + half and half so 'fractal' shows 50.00% for each
>> + (meaning that it assumes 100% total overhead of 'foo').
>> +
>> + The 'graph' uses absolute overhead value of 'foo' as total so each of
>> + 'bar' and 'baz' callchain will have 20.00% of overhead.
>> +
>> + call-graph.order::
>> + This option controls print order of callchains. The default is
>> + 'callee' which means callee is printed at top and then followed by its
>> + caller and so on. The 'caller' prints it in reverse order.
>> +
>> + If this option is not set and report.children or top.children is
>> + set to true (or the equivalent command line option is given),
>> + the default value of this option is changed to 'caller' for the
>> + execution of 'perf report' or 'perf top'. Other commands will
>> + still default to 'callee'.
>> +
>> + call-graph.sort-key::
>> + The callchains are merged if they contain same information.
>> + The sort-key option determines a way to compare the callchains.
>> + A value of 'sort-key' can be 'function' or 'address'.
>> + The default is 'function'.
>> +
>> + call-graph.threshold::
>> + When there're many callchains it'd print tons of lines. So perf omits
>> + small callchains under a certain overhead (threshold) and this option
>> + control the threashold. Default is 0.5 (%).
>
> s/threashold/threshold/
>
> Also it'd be better to mention that the overhead is calculated by
> value depends on call-graph.print-type.
>
>
>> +
>> + call-graph.print-limit::
>> + This is another way to control the number of callchains printed for a
>> + single entry. Default is 0 which means no limitation.
>
> This is a maximum number of lines of callchain printed for a single
> histogram entry.
>
> Thanks,
> Namhyung
>
>
>> +
>> SEE ALSO
>> --------
>> linkperf:perf[1]
>> --
>> 1.9.1

2015-11-30 05:04:10

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 10/24] perf config: Document variables for 'call-graph' section in man page

On Mon, Nov 30, 2015 at 10:42:00AM +0900, Taeung Song wrote:
> Hi, Namhyung

Hi Taeung,

> > On Nov 18, 2015, at 11:51 AM, Namhyung Kim <[email protected]> wrote:
> >
> > On Tue, Nov 17, 2015 at 10:53:30PM +0900, Taeung Song wrote:
> >> Explain 'call-graph' section and its variables.
> >>
> >> 'record-mode', 'dump-size', 'print-type', 'order',
> >> 'sort-key', 'threshold' and 'print-limit'.
> >>
> >> Cc: Namhyung Kim <[email protected]>
> >> Cc: Jiri Olsa <[email protected]>
> >> Signed-off-by: Taeung Song <[email protected]>
> >> ---
> >> tools/perf/Documentation/perf-config.txt | 65 ++++++++++++++++++++++++++++++++
> >> 1 file changed, 65 insertions(+)
> >>
> >> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> >> index 7d386d4..dc659d6 100644
> >> --- a/tools/perf/Documentation/perf-config.txt
> >> +++ b/tools/perf/Documentation/perf-config.txt
> >> @@ -285,6 +285,71 @@ ui.*::
> >> There're columns as header 'Overhead', 'Children', 'Shared Object', 'Symbol', 'self'.
> >> If this option is false, they are hiden. This option is only applied to TUI.
> >>
> >> +call-graph.*::
> >> + When sub-commands 'top' and 'report' work with -g/—-children
> >> + there're options in control of call-graph.
> >> +
> >> + call-graph.record-mode::
> >> + The record-mode can be 'fp' (frame pointer) and 'dwarf'.
> >
> > Also 'lbr' can be used, but it only work for recent intel cpus.
> >
> >
> >> + The value of 'dwarf' is effective only if perf detect needed library
> >> + (libunwind or a recent version of libdw). Also it doesn't *require*
> >> + the dump-size option since it can use the default value of 8192 if
> >> + missing.
> >
> > I think the last sentence can be omitted.
> >
> >
> >> +
> >> + call-graph.dump-size::
> >> + The size of stack to dump in order to do post-unwinding. Default is 8192 (byte).
> >> + When using dwarf into record-mode this option should have a value.
> >
> > This contradicts the above, it'll use the default size if omitted.
> >
> >
> >> +
> >> + call-graph.print-type::
> >> + The print-types can be graph (graph absolute), fractal (graph relative), flat.

The 'folded' print type was added recently. Please update it too.


> >> + This option controls a way to show overhead for each callchain entry.
> >> + Suppose a following example.
> >> +
> >> + Overhead Symbols
> >> + ........ .......
> >> + 40.00% foo
> >> + |
> >> + --- foo
> >> + |
> >> + |--50.00%-- bar
> >> + | main
> >> + |
> >> + --50.00%-- baz
> >> + main
> >
> > ^
> > it needs one more whitespace
> >
>
> I checked this patch file and whitespace and tab characters on it.
> But I think the lacking whitespace because of mail client.
> After 'make install’ I checked it but there is no lack of whitespace.
> Are there different problems that I missed ?

I meant whitespace in the callchain graph (i.e. 'bar' and 'baz' should
be aligned). But I think I was wrong - it should look like below:


Overhead Symbols
........ .......
40.00% foo
|
---foo
|
|--50.00%--bar
| main
|
--50.00%--baz
main


Maybe it's because you used TAB characters for indent?

Thanks,
Namhyung


>
> >
> >> +
> >> + This output is a 'fractal' format. The 'foo' came from 'bar' and 'baz' exactly
> >> + half and half so 'fractal' shows 50.00% for each
> >> + (meaning that it assumes 100% total overhead of 'foo').
> >> +
> >> + The 'graph' uses absolute overhead value of 'foo' as total so each of
> >> + 'bar' and 'baz' callchain will have 20.00% of overhead.
> >> +
> >> + call-graph.order::
> >> + This option controls print order of callchains. The default is
> >> + 'callee' which means callee is printed at top and then followed by its
> >> + caller and so on. The 'caller' prints it in reverse order.
> >> +
> >> + If this option is not set and report.children or top.children is
> >> + set to true (or the equivalent command line option is given),
> >> + the default value of this option is changed to 'caller' for the
> >> + execution of 'perf report' or 'perf top'. Other commands will
> >> + still default to 'callee'.
> >> +
> >> + call-graph.sort-key::
> >> + The callchains are merged if they contain same information.
> >> + The sort-key option determines a way to compare the callchains.
> >> + A value of 'sort-key' can be 'function' or 'address'.
> >> + The default is 'function'.
> >> +
> >> + call-graph.threshold::
> >> + When there're many callchains it'd print tons of lines. So perf omits
> >> + small callchains under a certain overhead (threshold) and this option
> >> + control the threashold. Default is 0.5 (%).
> >
> > s/threashold/threshold/
> >
> > Also it'd be better to mention that the overhead is calculated by
> > value depends on call-graph.print-type.
> >
> >
> >> +
> >> + call-graph.print-limit::
> >> + This is another way to control the number of callchains printed for a
> >> + single entry. Default is 0 which means no limitation.
> >
> > This is a maximum number of lines of callchain printed for a single
> > histogram entry.
> >
> > Thanks,
> > Namhyung
> >
> >
> >> +
> >> SEE ALSO
> >> --------
> >> linkperf:perf[1]
> >> --
> >> 1.9.1
>

2015-12-01 03:59:41

by Taeung Song

[permalink] [raw]
Subject: Re: [PATCH v11 03/24] perf config: Document variables for 'color' section in man page

Hi, Namhyung

> On Nov 18, 2015, at 8:47 AM, Namhyung Kim <[email protected]> wrote:
>
> On Tue, Nov 17, 2015 at 10:53:23PM +0900, Taeung Song wrote:
>> Explain 'color' section and its variables.
>>
>> 'top', 'medium', 'normal', 'selected',
>> 'code', 'addr' and 'root'.
>>
>> Cc: Namhyung Kim <[email protected]>
>> Cc: Jiri Olsa <[email protected]>
>> Signed-off-by: Taeung Song <[email protected]>
>> ---
>> tools/perf/Documentation/perf-config.txt | 44 ++++++++++++++++++++++++++++++++
>> 1 file changed, 44 insertions(+)
>>
>> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
>> index dfdab9c..84a982b 100644
>> --- a/tools/perf/Documentation/perf-config.txt
>> +++ b/tools/perf/Documentation/perf-config.txt
>> @@ -98,6 +98,50 @@ Given a $HOME/.perfconfig like this:
>> order = caller
>> sort-key = function
>>
>> +Variables
>> +~~~~~~~~~
>> +
>> +colors.*::
>> + The variables for customizing the colors used in the output for the
>> + 'report', 'top' and annotate in the TUI. They should specify the
>
> The 'annotate' also needs to be surrounded by single quotes.
>
>
>> + background and foreground colors, separated by a comma, for example:
>
> I think 'foreground and background' is better due to the order.
>
>
>> +
>> + medium = green, lightgray
>> +
>> + If you want to use the color configured for you terminal, just leave it
>> + as 'default', for example:
>> +
>> + medium = default, lightgray
>> +
>> + Available colors:
>> + red, green, default, black, blue, white, magenta, lightgray
>
> I don't know about the libslang color scheme, but it seems that the
> standard color names like 'yellow', 'cyan' and 'gray' are also
> available.
>
>
>> +
>> + colors.top::
>> + 'top' means a overhead percentage which is more than 5%.
>> + And values of this variable specify percentage colors.
>> + Basic key values are foreground-color 'red' and
>> + background-color 'default'.
>> + colors.medium::
>> + 'medium' means a overhead percentage which has more than 0.5%.
>> + Default values are 'green' and 'default'.
>> + colors.normal::
>> + 'normal' means the rest of overhead percentages
>> + except 'top', 'medium', 'selected'.
>> + Default values are 'lightgray' and 'default'.
>> + colors.selected::
>> + This selects the colors for the current entry in a list of entries
>> + from sub-commands (top,report,annotate).
>> + Default values are 'white' and 'lightgray'.
>
> Isn't it 'black' and 'lightgray'?
>
>
>> + colors.code::
>> + Colors for arrows and lines in jumps on assembly code listings
>> + such as 'jns','jmp','jane',etc. Default values are 'blue', 'default'.
>
> Hmm.. I thought this is for source code displayed with annotate
> output, but it's only for jump arrows? Maybe it's better to rename
> this then.. Anyway it's a different problem.
>

I rechecked the config (colors.code) but the colors are only for jump arrows.
So, I’ll send a patch to rename this config.


Thanks,
Taeung

>
>> + colors.addr::
>> + This selects colors for addresses from 'annotate'.
>> + Default values are 'magenta', 'default'.
>> + colors.root::
>> + Colors for headers in the output of a sub-command 'top'.
>
> It also works for 'report'.
>
> Thanks,
> Namhyung
>
>
>> + Default values are 'white', 'blue'.
>> +
>> SEE ALSO
>> --------
>> linkperf:perf[1]
>> --
>> 1.9.1

2015-12-01 16:17:59

by Taeung Song

[permalink] [raw]
Subject: Re: [PATCH v11 07/24] perf config: Document variables for 'help' section in man page

Hi, Namhyung

> On Nov 18, 2015, at 9:45 AM, Namhyung Kim <[email protected]> wrote:
>
> On Tue, Nov 17, 2015 at 10:53:27PM +0900, Taeung Song wrote:
>> Explain 'help.format' and 'help.autocorrect' variables.
>>
>> Cc: Namhyung Kim <[email protected]>
>> Cc: Jiri Olsa <[email protected]>
>> Signed-off-by: Taeung Song <[email protected]>
>> ---
>> tools/perf/Documentation/perf-config.txt | 21 +++++++++++++++++++++
>> 1 file changed, 21 insertions(+)
>>
>> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
>> index bfbeb34..88e9b88 100644
>> --- a/tools/perf/Documentation/perf-config.txt
>> +++ b/tools/perf/Documentation/perf-config.txt
>> @@ -242,6 +242,27 @@ annotate.*::
>>
>> │1 1382: movb $0x1,-0x270(%rbp)
>>
>> +help.*::
>> + help.format:: = man
>
> What is this '= man' part? Is it for default value? It looks inconsistent anyway.
>
>
>> + A format of manual page can be 'man', 'info', 'web' or 'html'.
>> + 'man' is default.
>
> I don't know we support other format of manual pages. Maybe asciidoc
> does the job for us, but do we really care? At least 'info' seems broken..
>

I rechecked source code for this values and tested them.
Only a ‘man’ value work with perf without any problems.
And code for ‘web', ‘html’ and ‘info’ has a few errors.

So, IMHO:), I thought that if the code for them was fixed,
maybe they could be used as values for help.format.

Or is it better to remove/disable this values (web, html, info) ?
(First of all I'll try to make patch for the errors.)


Thanks,
Taeung

>
>> + help.autocorrect:: = 0
>> + Automatically correct and execute mistyped commands after
>> + waiting for the given number of deciseconds (0.1 sec).
>> + Let's see a example. If a mistyped sub-command is executed like 'perf mistyped-command'
>
> s/a example/an example/
>
>> + and this option is 0, the output is as below.
>> +
>> + perf: 'mistyped-command' is not a perf-command. See 'perf --help'.
>> +
>> + Or if this option is more than 1, the output can be such as.
>> +
>> + WARNING: You called a perf program named 'mistyped-command', which does not exist.
>> + Continuing under the assumption that you meant 'with-kcore'
>> + in 0.1 seconds automatically...
>> + Usage: perf-with-kcore <perf sub-command> <perf.data directory> [<sub-command options> [ -- <workload>]]
>> + <perf sub-command> can be record, script, report or inject
>> + or: perf-with-kcore fix_buildid_cache_permissions
>
> I wasn't aware of this feature and it seems completely broken. If
> it's a leftover from the git codebase, we'd better either to
> disable/remove it or fix it.
>
> Thanks,
> Namhyung
>
>
>> +
>> SEE ALSO
>> --------
>> linkperf:perf[1]
>> --
>> 1.9.1

2016-03-04 12:45:52

by Taeung Song

[permalink] [raw]
Subject: Re: [PATCH v11 17/24] perf config: Collect configs to handle config variables

Hi, Namhyung and all

(I'm modifying this patch to be tidy)
I have a mere question about name of a variable for
current config list that contains section list which has key-value
pairs from ~/.perfconfig or $(sysconfdir)/perfconfig config file.

(This variable is designed to be used by several functions
that handle config information(key-value pairs).)

I used 'sections' for this variable (type is 'struct list_head'),
but IMHO, I think that renaming it is better e.g.

1) 'cfglist'
2) 'configlist'
3) 'config_list'
4) 'cfgset'
5) 'configset'
6) 'config_set'
... :-\

It is trivial question,
but I wanna know a opinion of other people. :-)

Thanks,
Taeung

On 11/18/2015 02:15 PM, Namhyung Kim wrote:
> On Tue, Nov 17, 2015 at 10:53:37PM +0900, Taeung Song wrote:
>> Collecting configs into list because of two reason.
>>
>> First of all, if there are same variables both user
>> and system config file, they all will be printed
>> when 'list' command work. But if config variables are
>> duplicated, user config variables should only be printed
>> because it has priority.
>>
>> Lastly, list into which configs is collected
>> will be required to keep and handle config variables
>> and values in the near furture. For example,
>> getting or setting functionality.
>>
>> And change show_config() function.
>> Old show_config() worked depending on perf_config().
>> New show_config() work using collected configs list.
>>
>> Cc: Jiri Olsa <[email protected]>
>> Signed-off-by: Taeung Song <[email protected]>
>
> Acked-by: Namhyung Kim <[email protected]>
>
> Thanks,
> Namhyung
>
>
>> ---
>> tools/perf/builtin-config.c | 150 ++++++++++++++++++++++++++++++++++++++++++--
>> tools/perf/util/cache.h | 13 ++++
>> 2 files changed, 158 insertions(+), 5 deletions(-)
>>
>> diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
>> index e0f8b41..185aa5e 100644
>> --- a/tools/perf/builtin-config.c
>> +++ b/tools/perf/builtin-config.c
>> @@ -32,13 +32,148 @@ static struct option config_options[] = {
>> OPT_END()
>> };
>>
>> -static int show_config(const char *key, const char *value,
>> - void *cb __maybe_unused)
>> +static struct config_section *find_section(struct list_head *sections,
>> + const char *section_name)
>> {
>> + struct config_section *section;
>> +
>> + list_for_each_entry(section, sections, list)
>> + if (!strcmp(section->name, section_name))
>> + return section;
>> +
>> + return NULL;
>> +}
>> +
>> +static struct config_element *find_element(const char *name,
>> + struct config_section *section)
>> +{
>> + struct config_element *element;
>> +
>> + list_for_each_entry(element, &section->element_head, list)
>> + if (!strcmp(element->name, name))
>> + return element;
>> +
>> + return NULL;
>> +}
>> +
>> +static void find_config(struct list_head *sections,
>> + struct config_section **section,
>> + struct config_element **element,
>> + const char *section_name, const char *name)
>> +{
>> + *section = find_section(sections, section_name);
>> +
>> + if (*section != NULL)
>> + *element = find_element(name, *section);
>> + else
>> + *element = NULL;
>> +}
>> +
>> +static struct config_section *init_section(const char *section_name)
>> +{
>> + struct config_section *section;
>> +
>> + section = zalloc(sizeof(*section));
>> + if (!section)
>> + return NULL;
>> +
>> + INIT_LIST_HEAD(&section->element_head);
>> + section->name = strdup(section_name);
>> + if (!section->name) {
>> + pr_err("%s: strdup failed\n", __func__);
>> + free(section);
>> + return NULL;
>> + }
>> +
>> + return section;
>> +}
>> +
>> +static int add_element(struct list_head *head,
>> + const char *name, const char *value)
>> +{
>> + struct config_element *element;
>> +
>> + element = zalloc(sizeof(*element));
>> + if (!element)
>> + return -1;
>> +
>> + element->name = strdup(name);
>> + if (!element->name) {
>> + pr_err("%s: strdup failed\n", __func__);
>> + free(element);
>> + return -1;
>> + }
>> if (value)
>> - printf("%s=%s\n", key, value);
>> + element->value = (char *)value;
>> else
>> - printf("%s\n", key);
>> + element->value = NULL;
>> +
>> + list_add_tail(&element->list, head);
>> + return 0;
>> +}
>> +
>> +static int collect_current_config(const char *var, const char *value,
>> + void *spec_sections)
>> +{
>> + int ret = -1;
>> + char *ptr, *key;
>> + char *section_name, *name;
>> + struct config_section *section = NULL;
>> + struct config_element *element = NULL;
>> + struct list_head *sections = (struct list_head *)spec_sections;
>> +
>> + key = ptr = strdup(var);
>> + if (!key) {
>> + pr_err("%s: strdup failed\n", __func__);
>> + return -1;
>> + }
>> +
>> + section_name = strsep(&ptr, ".");
>> + name = ptr;
>> + if (name == NULL || value == NULL)
>> + goto out_err;
>> +
>> + find_config(sections, &section, &element, section_name, name);
>> +
>> + if (!section) {
>> + section = init_section(section_name);
>> + if (!section)
>> + goto out_err;
>> + list_add_tail(&section->list, sections);
>> + }
>> +
>> + value = strdup(value);
>> + if (!value) {
>> + pr_err("%s: strdup failed\n", __func__);
>> + goto out_err;
>> + }
>> +
>> + if (!element)
>> + add_element(&section->element_head, name, value);
>> + else {
>> + free(element->value);
>> + element->value = (char *)value;
>> + }
>> +
>> + ret = 0;
>> +out_err:
>> + free(key);
>> + return ret;
>> +}
>> +
>> +static int show_config(struct list_head *sections)
>> +{
>> + struct config_section *section;
>> + struct config_element *element;
>> +
>> + if (list_empty(sections))
>> + return -1;
>> + list_for_each_entry(section, sections, list) {
>> + list_for_each_entry(element, &section->element_head, list) {
>> + printf("%s.%s=%s\n", section->name,
>> + element->name, element->value);
>> + }
>> + }
>>
>> return 0;
>> }
>> @@ -46,6 +181,7 @@ static int show_config(const char *key, const char *value,
>> int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
>> {
>> int ret = 0;
>> + struct list_head sections;
>>
>> argc = parse_options(argc, argv, config_options, config_usage,
>> PARSE_OPT_STOP_AT_NON_OPTION);
>> @@ -57,18 +193,22 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
>> return -1;
>> }
>>
>> + INIT_LIST_HEAD(&sections);
>> +
>> if (use_system_config)
>> config_exclusive_filename = perf_etc_perfconfig();
>> else if (use_user_config)
>> config_exclusive_filename = mkpath("%s/.perfconfig", getenv("HOME"));
>>
>> + perf_config(collect_current_config, &sections);
>> +
>> switch (actions) {
>> case ACTION_LIST:
>> if (argc) {
>> pr_err("Error: takes no arguments\n");
>> parse_options_usage(config_usage, config_options, "l", 1);
>> } else {
>> - ret = perf_config(show_config, NULL);
>> + ret = show_config(&sections);
>> if (ret < 0)
>> pr_err("Nothing configured, "
>> "please check your ~/.perfconfig file\n");
>> diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
>> index d1eb75f..e503371 100644
>> --- a/tools/perf/util/cache.h
>> +++ b/tools/perf/util/cache.h
>> @@ -1,6 +1,7 @@
>> #ifndef __PERF_CACHE_H
>> #define __PERF_CACHE_H
>>
>> +#include <linux/list.h>
>> #include <stdbool.h>
>> #include "util.h"
>> #include "strbuf.h"
>> @@ -19,6 +20,18 @@
>> #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
>> #define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
>>
>> +struct config_element {
>> + char *name;
>> + char *value;
>> + struct list_head list;
>> +};
>> +
>> +struct config_section {
>> + char *name;
>> + struct list_head element_head;
>> + struct list_head list;
>> +};
>> +
>> extern const char *config_exclusive_filename;
>>
>> typedef int (*config_fn_t)(const char *, const char *, void *);
>> --
>> 1.9.1
>>

2016-03-04 14:00:13

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v11 17/24] perf config: Collect configs to handle config variables

Hi Taeung,

On Fri, Mar 04, 2016 at 09:45:44PM +0900, Taeung Song wrote:
> Hi, Namhyung and all
>
> (I'm modifying this patch to be tidy)
> I have a mere question about name of a variable for
> current config list that contains section list which has key-value
> pairs from ~/.perfconfig or $(sysconfdir)/perfconfig config file.
>
> (This variable is designed to be used by several functions
> that handle config information(key-value pairs).)
>
> I used 'sections' for this variable (type is 'struct list_head'),
> but IMHO, I think that renaming it is better e.g.
>
> 1) 'cfglist'
> 2) 'configlist'
> 3) 'config_list'
> 4) 'cfgset'
> 5) 'configset'
> 6) 'config_set'
> ... :-\
>
> It is trivial question,
> but I wanna know a opinion of other people. :-)

I'd go with 3 or 6. Or simply 'configs' or 'perf_configs' is fine for
me.

Thanks,
Namhyung

2016-03-05 02:55:27

by Taeung Song

[permalink] [raw]
Subject: Re: [PATCH v11 17/24] perf config: Collect configs to handle config variables



On 03/04/2016 10:58 PM, Namhyung Kim wrote:
> Hi Taeung,
>
> On Fri, Mar 04, 2016 at 09:45:44PM +0900, Taeung Song wrote:
>> Hi, Namhyung and all
>>
>> (I'm modifying this patch to be tidy)
>> I have a mere question about name of a variable for
>> current config list that contains section list which has key-value
>> pairs from ~/.perfconfig or $(sysconfdir)/perfconfig config file.
>>
>> (This variable is designed to be used by several functions
>> that handle config information(key-value pairs).)
>>
>> I used 'sections' for this variable (type is 'struct list_head'),
>> but IMHO, I think that renaming it is better e.g.
>>
>> 1) 'cfglist'
>> 2) 'configlist'
>> 3) 'config_list'
>> 4) 'cfgset'
>> 5) 'configset'
>> 6) 'config_set'
>> ... :-\
>>
>> It is trivial question,
>> but I wanna know a opinion of other people. :-)
>
> I'd go with 3 or 6. Or simply 'configs' or 'perf_configs' is fine for
> me.
>

Thank you for your opinion. :-)

Taeung