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


Groups > linux.kernel > #1271526 > unrolled thread

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

Started byTaeung Song <treeze.taeung@gmail.com>
First post2015-11-17 19:40 +0100
Last post2015-11-26 09:30 +0100
Articles 20 on this page of 46 — 6 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v11 01/24] perf tools: Add 'perf-config' command Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
    [PATCH v11 22/24] perf config: Add 'set' feature Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
    [PATCH v11 14/24] perf config: Document 'pager.<subcommand>' variables in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 14/24] perf config: Document 'pager.<subcommand>'  variables in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 06:10 +0100
    [PATCH v11 19/24] perf config: Add a option 'skel' to perf-config Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
    [PATCH v11 13/24] perf config: Document 'man.viewer' variable in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 13/24] perf config: Document 'man.viewer' variable in  man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 06:00 +0100
    [PATCH v11 07/24] perf config: Document variables for 'help' section in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 07/24] perf config: Document variables for 'help'  section in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 01:50 +0100
    [PATCH v11 08/24] perf config: Document 'hist.percentage' variable in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 08/24] perf config: Document 'hist.percentage'  variable in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 02:00 +0100
    [PATCH v11 18/24] perf config: Add 'list-all' option to perf-config Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
    [PATCH v11 17/24] perf config: Collect configs to handle config variables Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 17/24] perf config: Collect configs to handle config  variables Namhyung Kim <namhyung@kernel.org> - 2015-11-18 06:20 +0100
    [PATCH v11 16/24] perf config: Add '--system' and '--user' options to select which config file is used Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 16/24] perf config: Add '--system' and '--user'  options to select which config file is used Namhyung Kim <namhyung@kernel.org> - 2015-11-18 06:20 +0100
    [PATCH v11 12/24] perf config: Document 'top.chidren' variable in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 12/24] perf config: Document 'top.chidren' variable  in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 04:10 +0100
    [PATCH v11 11/24] perf config: Document variables for 'report' section in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 11/24] perf config: Document variables for 'report'  section in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 04:10 +0100
    [PATCH v11 24/24] perf config: Add a option 'remove' to perf-config Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
    [PATCH v11 23/24] perf config: normalize a value depending on default type of it Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
    [PATCH v11 04/24] perf config: Document variables for 'tui' and 'gtk' sections in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 04/24] perf config: Document variables for 'tui' and  'gtk' sections in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 01:10 +0100
    [PATCH v11 06/24] perf config: Document variables for 'annotate' section in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 06/24] perf config: Document variables for 'annotate'  section in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 01:30 +0100
    [PATCH v11 10/24] perf config: Document variables for 'call-graph' section in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
      Re: [PATCH v11 10/24] perf config: Document variables for  'call-graph' section in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 04:00 +0100
        Re: [PATCH v11 10/24] perf config: Document variables for 'call-graph' section in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-30 02:50 +0100
          Re: [PATCH v11 10/24] perf config: Document variables for  'call-graph' section in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-30 06:10 +0100
    [PATCH v11 20/24] perf config: Add --verbose option for showing config description Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:40 +0100
    [PATCH v11 03/24] perf config: Document variables for 'color' section in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:50 +0100
      Re: [PATCH v11 03/24] perf config: Document variables for 'color'  section in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 00:50 +0100
    [PATCH v11 02/24] perf tools: Add perf-config document Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:50 +0100
      Re: [PATCH v11 02/24] perf tools: Add perf-config document Namhyung Kim <namhyung@kernel.org> - 2015-11-18 00:20 +0100
        Re: [PATCH v11 02/24] perf tools: Add perf-config document Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 20:30 +0100
          [PATCH v11 RESEND 02/24] perf tools: Add perf-config document Taeung Song <treeze.taeung@gmail.com> - 2015-11-22 11:20 +0100
            Re: [PATCH v11 RESEND 02/24] perf tools: Add perf-config document Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com> - 2015-11-23 15:20 +0100
            [tip:perf/core] perf config: Add initial man page tip-bot for Taeung Song <tipbot@zytor.com> - 2015-11-26 09:30 +0100
          Re: [PATCH v11 02/24] perf tools: Add perf-config document Taeung Song <treeze.taeung@gmail.com> - 2015-11-22 11:20 +0100
    [PATCH v11 09/24] perf config: Document 'ui.show-headers' variable in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:50 +0100
      Re: [PATCH v11 09/24] perf config: Document 'ui.show-headers'  variable in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 02:10 +0100
    [PATCH v11 05/24] perf config: Document 'buildid.dir' variable in man page Taeung Song <treeze.taeung@gmail.com> - 2015-11-17 19:50 +0100
      Re: [PATCH v11 05/24] perf config: Document 'buildid.dir' variable  in man page Namhyung Kim <namhyung@kernel.org> - 2015-11-18 01:10 +0100
    Re: [PATCH v11 01/24] perf tools: Add 'perf-config' command Namhyung Kim <namhyung@gmail.com> - 2015-11-17 23:40 +0100
    [tip:perf/core] perf tools: Add 'perf config' command tip-bot for Taeung Song <tipbot@zytor.com> - 2015-11-26 09:30 +0100

Page 1 of 3  [1] 2 3  Next page →


#1271526 — [PATCH v11 01/24] perf tools: Add 'perf-config' command

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 01/24] perf tools: Add 'perf-config' command
Message-ID<qvTkC-f2-7@gated-at.bofh.it>
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 <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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 <treeze.taeung@gmail.com>
+ *
+ */
+#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

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

[toc] | [next] | [standalone]


#1271528 — [PATCH v11 22/24] perf config: Add 'set' feature

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 22/24] perf config: Add 'set' feature
Message-ID<qvTkC-f2-5@gated-at.bofh.it>
In reply to#1271526
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@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


#1271530 — [PATCH v11 14/24] perf config: Document 'pager.<subcommand>' variables in man page

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 14/24] perf config: Document 'pager.<subcommand>' variables in man page
Message-ID<qvTkC-f2-21@gated-at.bofh.it>
In reply to#1271526
Explain 'pager.<subcommand>' variables.

Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


#1271846 — Re: [PATCH v11 14/24] perf config: Document 'pager.<subcommand>' variables in man page

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-18 06:10 +0100
SubjectRe: [PATCH v11 14/24] perf config: Document 'pager.<subcommand>' variables in man page
Message-ID<qw3ai-6MR-7@gated-at.bofh.it>
In reply to#1271530
On Tue, Nov 17, 2015 at 10:53:34PM +0900, Taeung Song wrote:
> Explain 'pager.<subcommand>' variables.
> 
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
> ---
>  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
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1271531 — [PATCH v11 19/24] perf config: Add a option 'skel' to perf-config

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 19/24] perf config: Add a option 'skel' to perf-config
Message-ID<qvTkC-f2-11@gated-at.bofh.it>
In reply to#1271526
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 <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


#1271532 — [PATCH v11 13/24] perf config: Document 'man.viewer' variable in man page

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 13/24] perf config: Document 'man.viewer' variable in man page
Message-ID<qvTkD-f2-29@gated-at.bofh.it>
In reply to#1271526
Explain 'man.viewer' variable.

Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


#1271845 — Re: [PATCH v11 13/24] perf config: Document 'man.viewer' variable in man page

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-18 06:00 +0100
SubjectRe: [PATCH v11 13/24] perf config: Document 'man.viewer' variable in man page
Message-ID<qw30C-6tK-1@gated-at.bofh.it>
In reply to#1271532
On Tue, Nov 17, 2015 at 10:53:33PM +0900, Taeung Song wrote:
> Explain 'man.viewer' variable.
> 
> Cc: Jiri Olsa <jolsa@redhat.com>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
> ---
>  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
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1271533 — [PATCH v11 07/24] perf config: Document variables for 'help' section in man page

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 07/24] perf config: Document variables for 'help' section in man page
Message-ID<qvTkD-f2-31@gated-at.bofh.it>
In reply to#1271526
Explain 'help.format' and 'help.autocorrect' variables.

Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


#1271777 — Re: [PATCH v11 07/24] perf config: Document variables for 'help' section in man page

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-18 01:50 +0100
SubjectRe: [PATCH v11 07/24] perf config: Document variables for 'help' section in man page
Message-ID<qvZ6F-3Vi-1@gated-at.bofh.it>
In reply to#1271533
On Tue, Nov 17, 2015 at 10:53:27PM +0900, Taeung Song wrote:
> Explain 'help.format' and 'help.autocorrect' variables.
> 
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
> ---
>  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
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1271536 — [PATCH v11 08/24] perf config: Document 'hist.percentage' variable in man page

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 08/24] perf config: Document 'hist.percentage' variable in man page
Message-ID<qvTkD-f2-37@gated-at.bofh.it>
In reply to#1271526
Explain 'hist.percentage' variable.

Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


#1271788 — Re: [PATCH v11 08/24] perf config: Document 'hist.percentage' variable in man page

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-18 02:00 +0100
SubjectRe: [PATCH v11 08/24] perf config: Document 'hist.percentage' variable in man page
Message-ID<qvZgm-3YZ-13@gated-at.bofh.it>
In reply to#1271536
On Tue, Nov 17, 2015 at 10:53:28PM +0900, Taeung Song wrote:
> Explain 'hist.percentage' variable.
> 
> Cc: Jiri Olsa <jolsa@redhat.com>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>

Acked-by: Namhyung Kim <namhyung@kernel.org>

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

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


#1271539 — [PATCH v11 18/24] perf config: Add 'list-all' option to perf-config

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 18/24] perf config: Add 'list-all' option to perf-config
Message-ID<qvTkD-f2-47@gated-at.bofh.it>
In reply to#1271526
'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@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


#1271540 — [PATCH v11 17/24] perf config: Collect configs to handle config variables

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 17/24] perf config: Collect configs to handle config variables
Message-ID<qvTkD-f2-51@gated-at.bofh.it>
In reply to#1271526
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 <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


#1271851 — Re: [PATCH v11 17/24] perf config: Collect configs to handle config variables

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-18 06:20 +0100
SubjectRe: [PATCH v11 17/24] perf config: Collect configs to handle config variables
Message-ID<qw3jY-6QF-3@gated-at.bofh.it>
In reply to#1271540
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 <jolsa@redhat.com>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>

Acked-by: Namhyung Kim <namhyung@kernel.org>

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

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


#1271542 — [PATCH v11 16/24] perf config: Add '--system' and '--user' options to select which config file is used

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 16/24] perf config: Add '--system' and '--user' options to select which config file is used
Message-ID<qvTkE-f2-55@gated-at.bofh.it>
In reply to#1271526
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 <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


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

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-18 06:20 +0100
SubjectRe: [PATCH v11 16/24] perf config: Add '--system' and '--user' options to select which config file is used
Message-ID<qw3jY-6QF-1@gated-at.bofh.it>
In reply to#1271542
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 <jolsa@redhat.com>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>

Acked-by: Namhyung Kim <namhyung@kernel.org>

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

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


#1271544 — [PATCH v11 12/24] perf config: Document 'top.chidren' variable in man page

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 12/24] perf config: Document 'top.chidren' variable in man page
Message-ID<qvTkE-f2-61@gated-at.bofh.it>
In reply to#1271526
Explain 'top.children' variable.

Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


#1271824 — Re: [PATCH v11 12/24] perf config: Document 'top.chidren' variable in man page

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-18 04:10 +0100
SubjectRe: [PATCH v11 12/24] perf config: Document 'top.chidren' variable in man page
Message-ID<qw1ia-5rP-3@gated-at.bofh.it>
In reply to#1271544
On Tue, Nov 17, 2015 at 10:53:32PM +0900, Taeung Song wrote:
> Explain 'top.children' variable.
> 
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
> ---
>  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
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1271546 — [PATCH v11 11/24] perf config: Document variables for 'report' section in man page

FromTaeung Song <treeze.taeung@gmail.com>
Date2015-11-17 19:40 +0100
Subject[PATCH v11 11/24] perf config: Document variables for 'report' section in man page
Message-ID<qvTkE-f2-71@gated-at.bofh.it>
In reply to#1271526
Explain 'report' section's variables.

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

Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 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

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

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


#1271823 — Re: [PATCH v11 11/24] perf config: Document variables for 'report' section in man page

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-18 04:10 +0100
SubjectRe: [PATCH v11 11/24] perf config: Document variables for 'report' section in man page
Message-ID<qw1ia-5rP-1@gated-at.bofh.it>
In reply to#1271546
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 <namhyung@kernel.org>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
> ---
>  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
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | linux.kernel


csiph-web