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


Groups > linux.kernel > #1339167 > unrolled thread

[PATCHSET v16 0/8] perf config: Add several functionalities into perf-config

Started byTaeung Song <treeze.taeung@gmail.com>
First post2016-02-22 08:40 +0100
Last post2016-02-22 08:50 +0100
Articles 7 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCHSET v16 0/8] perf config: Add several functionalities into perf-config Taeung Song <treeze.taeung@gmail.com> - 2016-02-22 08:40 +0100
    [PATCH v16 4/8] perf config: Add --verbose option for showing config description Taeung Song <treeze.taeung@gmail.com> - 2016-02-22 08:50 +0100
    [PATCH v16 6/8] perf config: Add 'set' functionality Taeung Song <treeze.taeung@gmail.com> - 2016-02-22 08:50 +0100
    [PATCH v16 7/8] perf config: normalize a value depending on default type of it Taeung Song <treeze.taeung@gmail.com> - 2016-02-22 08:50 +0100
    [PATCH v16 2/8] perf config: Add 'list-all' option to perf-config Taeung Song <treeze.taeung@gmail.com> - 2016-02-22 08:50 +0100
    [PATCH v16 8/8] perf config: Add a option 'remove' to perf-config Taeung Song <treeze.taeung@gmail.com> - 2016-02-22 08:50 +0100
    [PATCH v16 5/8] perf config: Add 'get' functionality Taeung Song <treeze.taeung@gmail.com> - 2016-02-22 08:50 +0100

#1339167 — [PATCHSET v16 0/8] perf config: Add several functionalities into perf-config

FromTaeung Song <treeze.taeung@gmail.com>
Date2016-02-22 08:40 +0100
Subject[PATCHSET v16 0/8] perf config: Add several functionalities into perf-config
Message-ID<r4Tg5-2j1-7@gated-at.bofh.it>
Hello,

This patchset implements new functionalities for perf-config subcommand.
Add options (list-all, skel, verbose, remove) and
getting and setting functionalities into perf-config subcommand to more useful.

Changes in v16:
	- rebased onto the current tip/perf/core

Changes in v15:
	- separate out perf-config documention from this patchset
	- 'list' and 'list-all' options can also work with --verbose
	- 'get' functionality can also work with --verbose

Changes in v14:
	- change default value for report.group config [Namhyung]
	- make a distinction between user and system config file name
	  in error message when nothing configured
	- bug fix, segmentation fault of '--skel' option
	  of which reason is that a variable wasn't initialized
	- rename colors.code to colors.jump_arrows among config variables

Changes in v13:
	- add record.build-id config info to perf-config doc [Namhyung]
	- fill missing options info ('verbose', 'skel') on perf-config doc

Changes in v12:
	- modify perf-config documentation for each section to be more proper
	  and correct small typing errors [Namhyung]
	- add missing config variables that are group, show_linenr and
	  show_total_period [Namhyung]

Changes in v11:
	- add --skel option to produce an skeleton with the possible config
	  variables [Arnaldo]
	- add exception handling to --list option when nothing configured [Arnaldo]
	- default action without option is to show an usage message [Arnaldo]

Changes in v10:
	- split perf-config.txt into several patches for each section and replace some
	  paragraphes with better proper things [Arnaldo, Namhyung]
	- correct wrong default values for each variable [Namhyung]
	- remove the compare name function

Changes in v9:
	- add the compare name functionality treating '-' and '-' as being
	  the same thing for usability

Changes in v8:
	- correct small typing errors in a perf-config documention
	- split the collecting configs part into a separate patch
	- use new enum and struct for default configs instead of
	  hard-coded value [Namhyung]

Changes in v7:
	- modify explanations of syntax and options(color, gtk, tui, buildid, annotate)
	  to be better proper descriptions [Arnaldo]

Changes in v6:
	- split a 'set' feature patch into two patch to separate normalize_value() from it
	- bug fix : 'remove' and 'set' malfunctions when without a specific file-option
	  (If file-option isn't used, 'remove' feature had to use both user and system
	  config file and 'set' feature had to only handle user config file.)

Changes in v5:
	- simplify the switch statement in cmd_config()
	- set a config file path with '--system' or '--user'
	  instead of '--global' or '--system' [Namhyung]
	- the patch about 'get' and 'set 'split into two patchs [Namhyung]

Changes in v4:
	- if some config value is default value, notice it is '(default)' [Jirka]
	- if there wasn't any perfconfig file, perf-config malfunctioned
	  so add exception routine with '--global' and '--system'
	  option which can select perf config file path [Jirka]

Changes in v3:
	- add a config variable 'kmem.default' with a default value [Namhyung]

Changes in v2:
	- change option name of listing all configs as '--list-all'
	  instead of '--all' [Namhyung]
	- correct small infelicities or typing errors in a perf-config documention [Arnaldo]
	- declaration a global variable 'static struct default_configsets' has config
	  variables with default values instead of using a 'util/PERFCONFIG-DEFAULT' file.
	- add a function to normalize a value and check data type of it.
	- simplify parsing arguments as arguments is just divided by '=' and then
	  in front of '.' is a section, between '.' and '=' is a name,
	  and behind '=' is a value.
	- if run perf-config command without any option, perf-config work as '--list'.

Taeung Song (8):
  perf config: Collect configs to handle config variables
  perf config: Add 'list-all' option to perf-config
  perf config: Add a option 'skel' to perf-config
  perf config: Add --verbose option for showing config description
  perf config: Add 'get' functionality
  perf config: Add 'set' feature
  perf config: normalize a value depending on default type of it
  perf config: Add a option 'remove' to perf-config

 tools/perf/Documentation/perf-config.txt |  24 +
 tools/perf/builtin-config.c              | 723 ++++++++++++++++++++++++++++++-
 tools/perf/util/cache.h                  |  17 +
 tools/perf/util/config.c                 |  27 +-
 4 files changed, 777 insertions(+), 14 deletions(-)

-- 
2.5.0

[toc] | [next] | [standalone]


#1339172 — [PATCH v16 4/8] perf config: Add --verbose option for showing config description

FromTaeung Song <treeze.taeung@gmail.com>
Date2016-02-22 08:50 +0100
Subject[PATCH v16 4/8] perf config: Add --verbose option for showing config description
Message-ID<r4TpM-2pd-1@gated-at.bofh.it>
In reply to#1339167
To explain what each of variable options configures,
this option can be used with 'skel', 'list' and
'list-all' options, i.e.

    print the possible config variables with comments over each of them.
    # perf config -vk | --verbose --skel
    or
    print all or current config variables with descriptions
    # perf config -vl | --verbose --list
    # perf config -va | --verbose --list-all

Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 tools/perf/Documentation/perf-config.txt |   4 +
 tools/perf/builtin-config.c              | 186 +++++++++++++++++++++----------
 2 files changed, 130 insertions(+), 60 deletions(-)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 964879a..1da577f 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -41,6 +41,10 @@ OPTIONS
 --skel::
 	Produce an skeleton with the possible config variables.
 
+-v::
+--verbose::
+	Be more verbose. (show config description)
+
 CONFIGURATION FILE
 ------------------
 
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 6ab53b2..ad82074 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()
@@ -111,71 +113,117 @@ 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_JUMP_ARROWS, "colors", "jump_arrows", "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(ANNOTATE_SHOW_LINENR, "annotate", "show_linenr", false),
-	CONF_BOOL_VAR(ANNOTATE_SHOW_TOTAL_PERIOD, "annotate", "show_total_period", 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_GROUP, "report", "group", true),
-	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_JUMP_ARROWS, "colors", "jump_arrows", "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(ANNOTATE_SHOW_LINENR, "annotate", "show_linenr", false,
+		      "Show line numbers"),
+	CONF_BOOL_VAR(ANNOTATE_SHOW_TOTAL_PERIOD, "annotate", "show_total_period", false,
+		      "Show a column with the sum of periods"),
+	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_GROUP, "report", "group", true,
+		      "Show event group information together"),
+	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()
 };
 
@@ -299,6 +347,8 @@ static int show_skel_config(void)
 			section = 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);
 	}
@@ -319,6 +369,9 @@ static int show_all_config(struct list_head *sections)
 		find_config(sections, &section, &element,
 			    config->section, config->name);
 
+		if (verbose)
+			printf("\n# %s\n", config->desc);
+
 		if (!element) {
 			char *value = get_value(config);
 
@@ -402,6 +455,7 @@ out_err:
 
 static int show_config(struct list_head *sections)
 {
+	int i;
 	struct config_section *section;
 	struct config_element *element;
 
@@ -409,6 +463,18 @@ static int show_config(struct list_head *sections)
 		return -1;
 	list_for_each_entry(section, sections, list) {
 		list_for_each_entry(element, &section->element_head, list) {
+			if (verbose) {
+				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, element->name)) {
+						printf("\n# %s\n", config->desc);
+						break;
+					}
+				}
+			}
+
 			printf("%s.%s=%s\n", section->name,
 				       element->name, element->value);
 		}
-- 
2.5.0

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


#1339173 — [PATCH v16 6/8] perf config: Add 'set' functionality

FromTaeung Song <treeze.taeung@gmail.com>
Date2016-02-22 08:50 +0100
Subject[PATCH v16 6/8] perf config: Add 'set' functionality
Message-ID<r4TpM-2pd-5@gated-at.bofh.it>
In reply to#1339167
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 <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 tools/perf/Documentation/perf-config.txt |   2 +-
 tools/perf/builtin-config.c              | 122 +++++++++++++++++++++++++------
 tools/perf/util/cache.h                  |   5 +-
 tools/perf/util/config.c                 |  27 ++++++-
 4 files changed, 131 insertions(+), 25 deletions(-)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index f83e9de..52fdb4b 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 b7162ab..d2587c5 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
 };
 
@@ -405,7 +405,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;
@@ -418,7 +420,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);
@@ -442,6 +444,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)
 {
@@ -491,8 +526,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;
@@ -519,10 +556,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;
@@ -561,7 +612,9 @@ 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);
@@ -577,14 +630,22 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
 		return -1;
 	}
 
-	INIT_LIST_HEAD(&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)
-		config_exclusive_filename = perf_etc_perfconfig();
-	else if (use_user_config)
+	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;
-
-	perf_config(collect_current_config, &sections);
+	} else {
+		sections = &all_sections;
+		INIT_LIST_HEAD(&all_sections);
+		perf_config(collect_current_config, &all_sections);
+	}
 
 	switch (actions) {
 	case ACTION_SKEL:
@@ -595,7 +656,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:
@@ -606,7 +667,7 @@ 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) {
 				const char * config_filename = config_exclusive_filename;
 				if (!config_exclusive_filename)
@@ -617,11 +678,28 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
 		}
 		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 d5dcc85..9614afd 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -39,9 +39,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 4e72763..34eff22 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").
-- 
2.5.0

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


#1339174 — [PATCH v16 7/8] perf config: normalize a value depending on default type of it

FromTaeung Song <treeze.taeung@gmail.com>
Date2016-02-22 08:50 +0100
Subject[PATCH v16 7/8] perf config: normalize a value depending on default type of it
Message-ID<r4TpN-2pd-17@gated-at.bofh.it>
In reply to#1339167
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 <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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 d2587c5..bad8182 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -444,6 +444,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)
 {
@@ -452,11 +500,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) {
-- 
2.5.0

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


#1339176 — [PATCH v16 2/8] perf config: Add 'list-all' option to perf-config

FromTaeung Song <treeze.taeung@gmail.com>
Date2016-02-22 08:50 +0100
Subject[PATCH v16 2/8] perf config: Add 'list-all' option to perf-config
Message-ID<r4TpN-2pd-29@gated-at.bofh.it>
In reply to#1339167
'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 <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 tools/perf/Documentation/perf-config.txt |   6 +
 tools/perf/builtin-config.c              | 231 ++++++++++++++++++++++++++++++-
 2 files changed, 235 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 15949e2..d9fb8c3 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 c43234e..8a63119 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -21,17 +21,160 @@ 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_JUMP_ARROWS,
+	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_ANNOTATE_SHOW_LINENR,
+	CONFIG_ANNOTATE_SHOW_TOTAL_PERIOD,
+	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_GROUP,
+	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_JUMP_ARROWS, "colors", "jump_arrows", "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(ANNOTATE_SHOW_LINENR, "annotate", "show_linenr", false),
+	CONF_BOOL_VAR(ANNOTATE_SHOW_TOTAL_PERIOD, "annotate", "show_total_period", 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_GROUP, "report", "group", true),
+	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 +255,78 @@ 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++) {
+				struct config_item *config = &default_configs[i];
+
+				if (!strcmp(config->section, section->name) &&
+				    !strcmp(config->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)
 {
@@ -184,6 +399,9 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
 	struct list_head sections;
 	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);
+
 	argc = parse_options(argc, argv, config_options, config_usage,
 			     PARSE_OPT_STOP_AT_NON_OPTION);
 
@@ -204,10 +422,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) {
-- 
2.5.0

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


#1339177 — [PATCH v16 8/8] perf config: Add a option 'remove' to perf-config

FromTaeung Song <treeze.taeung@gmail.com>
Date2016-02-22 08:50 +0100
Subject[PATCH v16 8/8] perf config: Add a option 'remove' to perf-config
Message-ID<r4TpO-2pd-39@gated-at.bofh.it>
In reply to#1339167
A option 'remove' is to remove specific config variables.
For the syntax examples,

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

Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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 52fdb4b..89c1ceb 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -15,6 +15,8 @@ or
 'perf config' [<file-option>] -a | --list-all
 or
 'perf config' [<file-option>] -k | --skel
+or
+'perf config' [<file-option>] -r | --remove [section.name ...]
 
 DESCRIPTION
 -----------
@@ -47,6 +49,10 @@ OPTIONS
 --verbose::
 	Be more verbose. (show config description)
 
+-r::
+--remove::
+	Remove specific config variables.
+
 CONFIGURATION FILE
 ------------------
 
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index bad8182..7ba842c 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"),
@@ -499,7 +502,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 */
@@ -663,6 +672,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);
@@ -692,6 +702,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);
-- 
2.5.0

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


#1339178 — [PATCH v16 5/8] perf config: Add 'get' functionality

FromTaeung Song <treeze.taeung@gmail.com>
Date2016-02-22 08:50 +0100
Subject[PATCH v16 5/8] perf config: Add 'get' functionality
Message-ID<r4TpO-2pd-43@gated-at.bofh.it>
In reply to#1339167
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 <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 tools/perf/Documentation/perf-config.txt |  2 +
 tools/perf/builtin-config.c              | 87 ++++++++++++++++++++++++++++++--
 tools/perf/util/cache.h                  |  1 +
 3 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 1da577f..f83e9de 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 ad82074..b7162ab 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
 };
 
@@ -404,6 +404,44 @@ 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);
+
+	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", config->section, config->name);
+			if (!section && !element)
+				printf("=%s (default)", value);
+			else
+				printf("=%s", element->value);
+			printf("\n");
+			free(value);
+			return 0;
+		}
+	}
+
+	if (section && element) {
+		printf("%s.%s=%s\n", section->name,
+		       element->name, element->value);
+		return 0;
+	}
+
+	return -1;
+}
+
 static int collect_current_config(const char *var, const char *value,
 				  void *spec_sections)
 {
@@ -453,6 +491,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)
 {
 	int i;
@@ -485,7 +560,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;
 	char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));
 
@@ -523,7 +598,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");
@@ -543,7 +617,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 92cd739..d5dcc85 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -39,6 +39,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 *);
-- 
2.5.0

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web