[PATCH v7 3/7] perf config: Add default section and item arrays for 'colors' config
Actual variable for configs of 'colors' section is like below. (at ui/browser.c) static struct ui_browser_colorset { const char *name, *fg, *bg; int colorset; } ui_browser__colorsets[] = { { .colorset = HE_COLORSET_TOP, .name = "top", .fg = "red", .bg = "default", }, ... But I suggest using default config arrays for 'colors' section that contain all default config key-value pairs for it. In near future, this array will be used on ui/browser.c because of setting default values of actual variables for 'colors' config. Cc: Namhyung Kim Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Wang Nan Cc: Alexander Shishkin Signed-off-by: Taeung Song --- tools/perf/util/config.c | 15 +++ tools/perf/util/config.h | 17 + 2 files changed, 32 insertions(+) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 18dae74..a0c0170 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -30,6 +30,21 @@ static struct perf_config_set *config_set; const char *config_exclusive_filename; +const struct default_config_item colors_config_items[] = { + CONF_STR_VAR("top", "red, default"), + CONF_STR_VAR("medium", "green, default"), + CONF_STR_VAR("normal", "default, default"), + CONF_STR_VAR("selected", "black, yellow"), + CONF_STR_VAR("jump_arrows", "blue, default"), + CONF_STR_VAR("addr", "magenta, default"), + CONF_STR_VAR("root", "white, blue"), + CONF_END() +}; + +const struct default_config_section default_sections[] = { + { .name = "colors", .items = colors_config_items }, +}; + static int get_next_char(void) { int c; diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index 613900f..b9190fe 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -73,6 +73,20 @@ enum perf_config_type { CONFIG_TYPE_STRING }; +enum config_section_idx { + CONFIG_COLORS, +}; + +enum colors_config_items_idx { + CONFIG_COLORS_TOP, + CONFIG_COLORS_MEDIUM, + CONFIG_COLORS_NORMAL, + CONFIG_COLORS_SELECTED, + CONFIG_COLORS_JUMP_ARROWS, + CONFIG_COLORS_ADDR, + CONFIG_COLORS_ROOT, +}; + struct default_config_item { const char *name; union { @@ -112,4 +126,7 @@ struct default_config_section { #define CONF_END() \ { .name = NULL } +extern const struct default_config_section default_sections[]; +extern const struct default_config_item colors_config_items[]; + #endif /* __PERF_CONFIG_H */ -- 2.5.0
[PATCH v7 2/7] perf config: Add macros assigning key-value pairs to default_config_item
In near future, default_config_item arrays will be added (e.g. const struct default_config_item colors_config_items[]) To simply assign config key-value pairs to default_config_item, add macros that are CONF_VAR() and CONF_*_VAR() for each type. Cc: Namhyung Kim Cc: Jiri Olsa Cc: Wang Nan Cc: Masami Hiramatsu Cc: Alexander Shishkin Signed-off-by: Taeung Song --- tools/perf/util/config.h | 20 1 file changed, 20 insertions(+) diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index 1fd8e4c..613900f 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -92,4 +92,24 @@ struct default_config_section { const struct default_config_item *items; }; +#define CONF_VAR(_name, _field, _val, _type) \ + { .name = _name, .value._field = _val, .type = _type } + +#define CONF_BOOL_VAR(_name, _val) \ + CONF_VAR(_name, b, _val, CONFIG_TYPE_BOOL) +#define CONF_INT_VAR(_name, _val) \ + CONF_VAR(_name, i, _val, CONFIG_TYPE_INT) +#define CONF_LONG_VAR(_name, _val) \ + CONF_VAR(_name, l, _val, CONFIG_TYPE_LONG) +#define CONF_U64_VAR(_name, _val) \ + CONF_VAR(_name, ll, _val, CONFIG_TYPE_U64) +#define CONF_FLOAT_VAR(_name, _val)\ + CONF_VAR(_name, f, _val, CONFIG_TYPE_FLOAT) +#define CONF_DOUBLE_VAR(_name, _val) \ + CONF_VAR(_name, d, _val, CONFIG_TYPE_DOUBLE) +#define CONF_STR_VAR(_name, _val) \ + CONF_VAR(_name, s, _val, CONFIG_TYPE_STRING) +#define CONF_END() \ + { .name = NULL } + #endif /* __PERF_CONFIG_H */ -- 2.5.0
[PATCH v7 1/7] perf config: Introduce default_config_section and default_config_item for default config key-value pairs
When initializing default perf config values, we currently use values of actual type(int, bool, char *, etc.). For example, If there isn't user config value at ~/.perfconfig for 'annotate.use_offset' config variable, default value for it is 'true' bool type value in perf like below. At ui/browsers/annoate.c static struct annotate_browser_opt { bool hide_src_code, use_offset, jump_arrows, show_linenr, show_nr_jumps, show_total_period; } annotate_browser__opts = { .use_offset = true, .jump_arrows = true, }; But I suggest using 'struct default_config_section' and 'struct default_config_item' that can contain default config key-value pairs in order to initialize default config values with them, in near future. If we do, we could manage default perf config values at one spot (i.e. util/config.c) with default config arrays and it could be easy and simple to modify existing default config values or add default values for new config item. Cc: Namhyung Kim Cc: Jiri Olsa Cc: Wang Nan Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Alexander Shishkin Signed-off-by: Taeung Song --- tools/perf/util/config.h | 29 + 1 file changed, 29 insertions(+) diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index 6f813d4..1fd8e4c 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -63,4 +63,33 @@ void perf_config__refresh(void); perf_config_sections__for_each_entry(&set->sections, section) \ perf_config_items__for_each_entry(§ion->items, item) +enum perf_config_type { + CONFIG_TYPE_BOOL, + CONFIG_TYPE_INT, + CONFIG_TYPE_LONG, + CONFIG_TYPE_U64, + CONFIG_TYPE_FLOAT, + CONFIG_TYPE_DOUBLE, + CONFIG_TYPE_STRING +}; + +struct default_config_item { + const char *name; + union { + bool b; + int i; + u32 l; + u64 ll; + float f; + double d; + const char *s; + } value; + enum perf_config_type type; +}; + +struct default_config_section { + const char *name; + const struct default_config_item *items; +}; + #endif /* __PERF_CONFIG_H */ -- 2.5.0
[RFC PATCH v7 0/7] perf config: Introduce default config key-value pairs arrays
Hello, :) When initializing default perf config values, we currently use values of actual type(int, bool, char *, etc.). But I suggest using default config key-value pairs arrays. For example, If there isn't user config value at ~/.perfconfig for 'annotate.use_offset' config variable, default value for it is 'true' bool type value in perf like below. At ui/browsers/annoate.c static struct annotate_browser_opt { bool hide_src_code, use_offset, jump_arrows, show_linenr, show_nr_jumps, show_total_period; } annotate_browser__opts = { .use_offset = true, .jump_arrows = true, }; But if we use new config arrays that have all default config key-value pairs, we could initialize default config values with them. If we do, we can manage default perf config values at one spot (like util/config.c) and It can be easy and simple to modify existing default config values or add default values for new config item. For example, If we use new default config arrays and there isn't user config value for 'annoate.use_offset' default value for it will be set as annotate_config_items[CONFIG_ANNOATE_USE_OFFSET].value.b instead of actual boolean type value 'true'. IMHO, I think it would needed to use new default config arrays to manage default perf config values more effectively. And this pathset contains patchs for only 'colors' and 'annoate' section because waiting for other opinions. If you review this patchset, I'd appreciate it :-) Thanks, Taeung v7: - rebased on current acme/perf/core v6: - rename 'fore_back_colors' to simple 'colors' of ui_browser_colorset (Namhyung) - remove unnecssary whitespace changes of PATCH 4/7, 5/7 (Namhyung) - make more general macro instead of making accessor macro for each config section (Namhyung) v5: - rebased on current acme/perf/core v4: - rename 'fb_ground' to 'fore_back_colors' (Namhyung) - add struct default_config_section - split first patch[PATCH 1/7] as two - remove perf_default_config_init() at perf.c - rebased on current acme/perf/core v3: - remove default config arrays for the rest sections except 'colors' and 'annotate' - use combined {fore, back}ground colors instead of each two color - introduce perf_default_config_init() that call all default_*_config_init() for each config section v2: - rename 'ui_browser__config_gcolors' to 'ui_browser__config_colors' (Arnaldo) - change 'ground colors' to '{back, fore}ground colors' (Arnaldo) - use strtok + ltrim instead of strchr and while (isspace(*++bg)); (Arnaldo) Taeung Song (7): perf config: Introduce default_config_section and default_config_item for default config key-value pairs perf config: Add macros assigning key-value pairs to default_config_item perf config: Add default section and item arrays for 'colors' config perf config: Use combined {fore,back}ground colors value instead of each two color perf config: Initialize ui_browser__colorsets with default config items perf config: Add default section and item arrays for 'annotate' config perf config: Initialize annotate_browser__opts with default config items tools/perf/ui/browser.c | 64 +-- tools/perf/ui/browsers/annotate.c | 16 ++-- tools/perf/util/config.c | 26 + tools/perf/util/config.h | 80 +++ 4 files changed, 154 insertions(+), 32 deletions(-) -- 2.5.0
[PATCH v7 6/7] perf config: Add default section and item arrays for 'annotate' config
Actual variable for configs of 'annotate' section is like below. (at ui/browsers/annoate.c) static struct annotate_browser_opt { bool hide_src_code, use_offset, jump_arrows, show_linenr, show_nr_jumps, show_total_period; } annotate_browser__opts = { .use_offset = true, .jump_arrows = true, }; But I suggest using default config arrays for 'annotate' section that contain all default config key-value pairs for it. In near future, this arrays will be used on ui/browsers/annoate.c because of setting default values of actual variables for 'annotate' config. Cc: Namhyung Kim Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Wang Nan Cc: Alexander Shishkin Signed-off-by: Taeung Song --- tools/perf/util/config.c | 11 +++ tools/perf/util/config.h | 11 +++ 2 files changed, 22 insertions(+) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index a0c0170..d8d5415 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -41,8 +41,19 @@ const struct default_config_item colors_config_items[] = { CONF_END() }; +const struct default_config_item annotate_config_items[] = { + CONF_BOOL_VAR("hide_src_code", false), + CONF_BOOL_VAR("use_offset", true), + CONF_BOOL_VAR("jump_arrows", true), + CONF_BOOL_VAR("show_nr_jumps", false), + CONF_BOOL_VAR("show_linenr", false), + CONF_BOOL_VAR("show_total_period", false), + CONF_END() +}; + const struct default_config_section default_sections[] = { { .name = "colors", .items = colors_config_items }, + { .name = "annotate", .items = annotate_config_items }, }; static int get_next_char(void) diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index b9190fe..2fcfd51 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -75,6 +75,7 @@ enum perf_config_type { enum config_section_idx { CONFIG_COLORS, + CONFIG_ANNOTATE, }; enum colors_config_items_idx { @@ -87,6 +88,15 @@ enum colors_config_items_idx { CONFIG_COLORS_ROOT, }; +enum annotate_config_items_idx { + 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, +}; + struct default_config_item { const char *name; union { @@ -128,5 +138,6 @@ struct default_config_section { extern const struct default_config_section default_sections[]; extern const struct default_config_item colors_config_items[]; +extern const struct default_config_item annotate_config_items[]; #endif /* __PERF_CONFIG_H */ -- 2.5.0
[PATCH v7 7/7] perf config: Initialize annotate_browser__opts with default config items
Set default config values for 'annotate' section with 'annotate_config_items[]' instead of actual bool type values. (e.g. using annotate_config_items[CONFIG_ANNOTATE_USE_OFFSET].value.b instead of 'true' bool type value for 'annotate.use_offset'.) Cc: Namhyung Kim Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Wang Nan Cc: Alexander Shishkin Signed-off-by: Taeung Song --- tools/perf/ui/browsers/annotate.c | 16 tools/perf/util/config.h | 3 +++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 29dc6d2..7ab9875 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -38,10 +38,7 @@ static struct annotate_browser_opt { show_linenr, show_nr_jumps, show_total_period; -} annotate_browser__opts = { - .use_offset = true, - .jump_arrows= true, -}; +} annotate_browser__opts; struct annotate_browser { struct ui_browser b; @@ -1157,7 +1154,18 @@ static int annotate__config(const char *var, const char *value, return 0; } +static void default_annotate_config_init(void) +{ + annotate_browser__opts.hide_src_code = CONF_DEFAULT_BOOL(ANNOTATE, HIDE_SRC_CODE); + annotate_browser__opts.use_offset = CONF_DEFAULT_BOOL(ANNOTATE, USE_OFFSET); + annotate_browser__opts.jump_arrows = CONF_DEFAULT_BOOL(ANNOTATE, JUMP_ARROWS); + annotate_browser__opts.show_linenr = CONF_DEFAULT_BOOL(ANNOTATE, SHOW_LINENR); + annotate_browser__opts.show_nr_jumps = CONF_DEFAULT_BOOL(ANNOTATE, SHOW_NR_JUMPS); + annotate_browser__opts.show_total_period = CONF_DEFAULT_BOOL(ANNOTATE, SHOW_TOTAL_PERIOD); +} + void annotate_browser__init(void) { + default_annotate_config_init(); perf_config(annotate__config, NULL); } diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index 2fcfd51..76f5b21 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -136,6 +136,9 @@ struct default_config_section { #define CONF_END() \ { .name = NULL } +#define CONF_DEFAULT_BOOL(sec, name) \ + default_sections[CONFIG_##sec].items[CONFIG_##sec##_##name].value.b + extern const struct default_config_section default_sections[]; extern const struct default_config_item colors_config_items[]; extern const struct default_config_item annotate_config_items[]; -- 2.5.0
[PATCH v7 4/7] perf config: Use combined {fore,back}ground colors value instead of each two color
To easily set default config values into actual variables for 'colors' config, it would be better that actual variables for each 'colors' config also have only one value like 'default_config_item' type. If we use combined {fore,back}ground colors values in ui_browser_colorset, it smoothly work to initialize default config values for 'colors' config by 'colors_config_items' array that contains default values for it at util/config.c. because both actual variable and config item of 'colors_config_items' are equal in the number of values (as just one). Cc: Namhyung Kim Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Wang Nan Cc: Alexander Shishkin Signed-off-by: Taeung Song --- tools/perf/ui/browser.c | 53 +++-- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 3eb3edb..31e2028 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -503,61 +503,53 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *browser) } static struct ui_browser_colorset { - const char *name, *fg, *bg; + const char *name, *colors; int colorset; } ui_browser__colorsets[] = { { .colorset = HE_COLORSET_TOP, .name = "top", - .fg = "red", - .bg = "default", + .colors = "red, default", }, { .colorset = HE_COLORSET_MEDIUM, .name = "medium", - .fg = "green", - .bg = "default", + .colors = "green, default", }, { .colorset = HE_COLORSET_NORMAL, .name = "normal", - .fg = "default", - .bg = "default", + .colors = "default, default", }, { .colorset = HE_COLORSET_SELECTED, .name = "selected", - .fg = "black", - .bg = "yellow", + .colors = "black, yellow", }, { .colorset = HE_COLORSET_JUMP_ARROWS, .name = "jump_arrows", - .fg = "blue", - .bg = "default", + .colors = "blue, default", }, { .colorset = HE_COLORSET_ADDR, .name = "addr", - .fg = "magenta", - .bg = "default", + .colors = "magenta, default", }, { .colorset = HE_COLORSET_ROOT, .name = "root", - .fg = "white", - .bg = "blue", + .colors = "white, blue", }, { .name = NULL, } }; - static int ui_browser__color_config(const char *var, const char *value, void *data __maybe_unused) { - char *fg = NULL, *bg; + char *colors; int i; /* same dir for all commands */ @@ -570,22 +562,18 @@ static int ui_browser__color_config(const char *var, const char *value, if (strcmp(ui_browser__colorsets[i].name, name) != 0) continue; - fg = strdup(value); - if (fg == NULL) - break; + if (strstr(value, ",") == NULL) + return -1; - bg = strchr(fg, ','); - if (bg == NULL) + colors = strdup(value); + if (colors == NULL) break; + ui_browser__colorsets[i].colors = colors; - *bg = '\0'; - while (isspace(*++bg)); - ui_browser__colorsets[i].bg = bg; - ui_browser__colorsets[i].fg = fg; return 0; } - free(fg); + free(colors); return -1; } @@ -743,8 +731,17 @@ void ui_browser__init(void) perf_config(ui_browser__color_config, NULL); while (ui_browser__colorsets[i].name) { + char *colors, *fg, *bg; struct ui_browser_colorset *c = &ui_browser__colorsets[i++]; - sltt_set_color(c->colorset, c->name, c->fg, c->bg); + + colors = strdup(c->colors); + if (fg == NULL) + break; + fg = strtok(colors, ","); + bg = strtok(NULL, ","); + bg = ltrim(bg); + sltt_set_color(c->colorset, c->name, fg, bg); + free(colors); } annotate_browser__init(); -- 2.5.0
[PATCH v7 5/7] perf config: Initialize ui_browser__colorsets with default config items
Set default config values for 'colors' section with 'colors_config_items[]' instead of actual const char * type values. (e.g. using colors_config_item[CONFIG_COLORS_TOP].value.s instead of "red, default" string value for 'colors.top') Cc: Namhyung Kim Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Wang Nan Cc: Alexander Shishkin Signed-off-by: Taeung Song --- tools/perf/ui/browser.c | 25 ++--- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 31e2028..598f434 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -509,37 +509,30 @@ static struct ui_browser_colorset { { .colorset = HE_COLORSET_TOP, .name = "top", - .colors = "red, default", }, { .colorset = HE_COLORSET_MEDIUM, .name = "medium", - .colors = "green, default", }, { .colorset = HE_COLORSET_NORMAL, .name = "normal", - .colors = "default, default", }, { .colorset = HE_COLORSET_SELECTED, .name = "selected", - .colors = "black, yellow", }, { .colorset = HE_COLORSET_JUMP_ARROWS, .name = "jump_arrows", - .colors = "blue, default", }, { .colorset = HE_COLORSET_ADDR, .name = "addr", - .colors = "magenta, default", }, { .colorset = HE_COLORSET_ROOT, .name = "root", - .colors = "white, blue", }, { .name = NULL, @@ -724,10 +717,28 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, __ui_browser__line_arrow_down(browser, column, start, end); } +static void default_colors_config_init(void) +{ + int i, j; + + for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) { + const char *name = ui_browser__colorsets[i].name; + + for (j = 0; colors_config_items[j].name != NULL; j++) { + if (!strcmp(name, colors_config_items[j].name)) { + ui_browser__colorsets[i].colors = + colors_config_items[j].value.s; + break; + } + } + } +} + void ui_browser__init(void) { int i = 0; + default_colors_config_init(); perf_config(ui_browser__color_config, NULL); while (ui_browser__colorsets[i].name) { -- 2.5.0
[RFC][PATCH v9 2/3] perf config: Reimplement perf_config() adding perf_config_init() and perf_config_finish()
Many sub-commands use perf_config() so everytime perf_config() is called, perf_config() always read config files. (i.e. user config '~/.perfconfig' and system config '$(sysconfdir)/perfconfig') But we need to use the config set that already contains all config key-value pairs to avoid this repetitive work reading the config files in perf_config(). (the config set mean a static variable 'config_set') In other words, if new perf_config_init() is called, only first time 'config_set' is initialized collecting all configs from the config files. And then we could use new perf_config() like old perf_config(). When a sub-command finished, free the config set by perf_config_finish() at run_builtin(). If we do, 'config_set' can be reused wherever perf_config() is called and a feature of old perf_config() is the same as new perf_config() work without the repetitive work that read the config files. In summary, in order to use features about configuration, we can call the functions from outside as below. # initialize a config set perf_config_init() # configure actual variables from a config set perf_config() # eliminate allocated config set perf_config_finish() # destroy existing config set and initialize a new config set. perf_config_refresh() Cc: Namhyung Kim Cc: Jiri Olsa Cc: Wang Nan Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Alexander Shishkin Signed-off-by: Taeung Song --- tools/perf/builtin-config.c | 4 ++ tools/perf/perf.c | 2 + tools/perf/util/config.c| 92 +++-- tools/perf/util/config.h| 29 ++ 4 files changed, 82 insertions(+), 45 deletions(-) diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index fe1b77f..cfd1036 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -80,6 +80,10 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) else if (use_user_config) config_exclusive_filename = user_config; + /* +* At only 'config' sub-command, individually use the config set +* because of reinitializing with options config file location. +*/ set = perf_config_set__new(); if (!set) { ret = -1; diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 35553c7..894bf5d0 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -391,6 +391,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) perf_env__set_cmdline(&perf_env, argc, argv); status = p->fn(argc, argv, prefix); + perf_config_finish(); exit_browser(status); perf_env__exit(&perf_env); bpf__clear(); @@ -558,6 +559,7 @@ int main(int argc, const char **argv) srandom(time(NULL)); + perf_config_init(); perf_config(perf_default_config, NULL); set_buildid_dir(NULL); diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 31e09a4..5b50134 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -26,6 +26,7 @@ static FILE *config_file; static const char *config_file_name; static int config_linenr; static int config_file_eof; +static struct perf_config_set *config_set; const char *config_exclusive_filename; @@ -478,51 +479,6 @@ static int perf_config_global(void) return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0); } -int perf_config(config_fn_t fn, void *data) -{ - int ret = -1; - const char *home = NULL; - - /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */ - if (config_exclusive_filename) - return perf_config_from_file(fn, config_exclusive_filename, data); - if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) { - if (perf_config_from_file(fn, perf_etc_perfconfig(), data) < 0) - goto out; - } - - home = getenv("HOME"); - if (perf_config_global() && home) { - char *user_config = strdup(mkpath("%s/.perfconfig", home)); - struct stat st; - - if (user_config == NULL) { - warning("Not enough memory to process %s/.perfconfig, " - "ignoring it.", home); - goto out; - } - - if (stat(user_config, &st) < 0) - goto out_free; - - if (st.st_uid && (st.st_uid != geteuid())) { - warning("File %s not owned by current user or root, " - "ignoring it.", user_config); - goto out_free; - } - - if (!st.st_size) - goto out_free
[PATCH v9 3/3] perf config: Reimplement show_config() using config_set__for_each
Lately config_set__for_each is added. In order to let show_config() be short and clear, remake this function using config_set__for_each macro Cc: Namhyung Kim Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Alexander Shishkin Cc: Wang Nan Signed-off-by: Taeung Song --- tools/perf/builtin-config.c | 17 + 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index cfd1036..c144643 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -37,23 +37,16 @@ static int show_config(struct perf_config_set *set) { struct perf_config_section *section; struct perf_config_item *item; - struct list_head *sections; if (set == NULL) return -1; - sections = &set->sections; - if (list_empty(sections)) - return -1; - - list_for_each_entry(section, sections, node) { - list_for_each_entry(item, §ion->items, node) { - char *value = item->value; + config_set__for_each(set, section, item) { + char *value = item->value; - if (value) - printf("%s.%s=%s\n", section->name, - item->name, value); - } + if (value) + printf("%s.%s=%s\n", section->name, + item->name, value); } return 0; -- 2.5.0
[REFACTORING][PATCH v9 1/3] perf config: Bring declarations about config from util/cache.h to util/config.h
Lately util/config.h has been added but util/cache.h has declarations of functions and a global variable for config features. To manage codes about configuration at one spot, move them to util/config.h and let source files that need config features include config.h And if the source files that included previous cache.h need only config.h, remove including cache.h. Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Wang Nan Signed-off-by: Taeung Song --- tools/perf/builtin-help.c | 2 +- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-record.c| 1 + tools/perf/builtin-report.c| 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/perf.c | 2 +- tools/perf/ui/browser.c| 2 +- tools/perf/ui/browsers/annotate.c | 1 + tools/perf/util/alias.c| 1 + tools/perf/util/cache.h| 12 tools/perf/util/color.c| 1 + tools/perf/util/config.h | 12 tools/perf/util/help-unknown-cmd.c | 1 + tools/perf/util/intel-pt.c | 1 + 14 files changed, 24 insertions(+), 18 deletions(-) diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index f9830c9..268ab73 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c @@ -4,7 +4,7 @@ * Builtin help command */ #include "perf.h" -#include "util/cache.h" +#include "util/config.h" #include "builtin.h" #include #include "common-cmds.h" diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 58adfee..4defe44 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -4,7 +4,7 @@ #include "util/evlist.h" #include "util/evsel.h" #include "util/util.h" -#include "util/cache.h" +#include "util/config.h" #include "util/symbol.h" #include "util/thread.h" #include "util/header.h" diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d4cf1b0..74e8133 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -13,6 +13,7 @@ #include "util/util.h" #include #include "util/parse-events.h" +#include "util/config.h" #include "util/callchain.h" #include "util/cgroup.h" diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 9f36b23..bcb49ff 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -8,7 +8,7 @@ #include "builtin.h" #include "util/util.h" -#include "util/cache.h" +#include "util/config.h" #include "util/annotate.h" #include "util/color.h" diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 81dba80..ec4cba6 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -22,7 +22,7 @@ #include "perf.h" #include "util/annotate.h" -#include "util/cache.h" +#include "util/config.h" #include "util/color.h" #include "util/evlist.h" #include "util/evsel.h" diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 15982ce..35553c7 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -10,7 +10,7 @@ #include "util/env.h" #include -#include "util/cache.h" +#include "util/config.h" #include "util/quote.h" #include #include "util/parse-events.h" diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index af68a9d..3eb3edb 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -1,5 +1,5 @@ #include "../util.h" -#include "../cache.h" +#include "../config.h" #include "../../perf.h" #include "libslang.h" #include "ui.h" diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 4fc208e..0e106bb 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -8,6 +8,7 @@ #include "../../util/sort.h" #include "../../util/symbol.h" #include "../../util/evsel.h" +#include "../../util/config.h" #include struct disasm_line_samples { diff --git a/tools/perf/util/alias.c b/tools/perf/util/alias.c index c0b43ee..6c80f83 100644 --- a/tools/perf/util/alias.c +++ b/tools/perf/util/alias.c @@ -1,4 +1,5 @@ #include "cache.h" +#include "config.h" static const char *alias_key; static char *alias_val; diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 0d814bb..5df4407 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -23,18 +23,6 @@ #define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR" #define PERF_PAGER_ENVIRONMENT "PERF_PAGER" -extern const char *config_exclusive_filename; - -t
[RFC][PATCH v9 0/3] perf config: Reimplement perf_config() adding perf_config_init() and perf_config_finish()
Hello, :) This patchset is to reimplement perf_config() for efficient config management. Everytime perf_config() is called, perf_config() always read config files. (i.e. user config '~/.perfconfig' and system config '$(sysconfdir)/perfconfig') But we need to use 'struct perf_config_set config_set' variable that already contains all config key-value pairs to avoid this repetitive work in perf_config(). In other words, if new perf_config() is called, only first time 'config_set' is initialized collecting all configs from config files and it work with perf_config_set__iter(). If we do, 'config_set' can be reused wherever using perf_config() and a feature of old perf_config() is the same as new perf_config() work without the repetitive work that read the config files. IMHO, I think this patchset is needed because not only the repetitive work should be avoided but also in near future, it would be smooth to manage perf configs. If you give me any feedback, I'd apprecicated it. :) Thanks, Taeung v9: - add config_set__for_each macro (Arnaldo) - the source files that only need config.h don't include cache.h (Arnaldo) - use 'config_set' as a static variable instead of a global variable. (Namhyung) - add perf_config_init(), perf_config_finish() and perf_config_refresh() (Namhyung) - remove [PATCH v8 4/5] perf config: Use zfree() instead of free() at perf_config_set__delete() - rebased onto current acme/perf/core - applied ([BUGFIX][PATCH v8 1/5] 826424) v8: - handle the error about NULL at perf_config_set__delete() - bring declarations about config from util/config.h to util/config.h - reimplement show_config() using perf_config_set__iter() instead of perf_config() - rebased onto perf-core-for-mingo-20160607 - applied ([PATCH v7 1/7] 25d8f48, [PATCH v7 2/7] 8beeb00) v7: - fill a missing crumb that assign NULL to 'set' variable in perf_config_set__new() (Arnaldo) - two patches applied ([PATCH v6 1/9] 78f71c9, [PATCH v6 3/9] 7db91f2) v6: - add printing error message when perf_config_set__iter() is failed - modify commit messages for bugfix 1~3 (PATCH 1/9 ~ 3/9) to help reviewers easily understand why them is needed v5: - solve the leak when perf_config_set__init() failed (Arnaldo) (to clear the problem it is needed to apply the bottom bugfix 1~3 patches) - bugfix 1) fix the problem of abnormal terminaltion at perf_parse_file() called by perf_config() - bugfix 2) if failed at collect_config(), finally free a config set after it is done instead of freeing the config set in the function - bugfix 3) handle NULL pointer exception of 'set' at collect_config() v4: - Keep perf_config_set__delete() as it is (Arnaldo) - Remove perf_config_set__check() (Arnaldo) - Keep the existing code about the config set at cmd_config() (Arnaldo) v3: - add freeing config set after sub-command work at run_builtin() (Namhyung) - remove needless code about the config set at cmd_config() - add a patch about a global variable 'config_set' v2: - split a patch into several patches - reimplement show_config() using new perf_config() - modify perf_config_set__delete using global variable 'config_set' - reset config set when only 'config' sub-commaned work because of options for config file location Taeung Song (3): perf config: Bring declarations about config from util/cache.h to util/config.h perf config: Reimplement perf_config() adding perf_config_init() and perf_config_finish() perf config: Reimplement show_config() using config_set__for_each tools/perf/builtin-config.c| 21 - tools/perf/builtin-help.c | 2 +- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-record.c| 1 + tools/perf/builtin-report.c| 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/perf.c | 4 +- tools/perf/ui/browser.c| 2 +- tools/perf/ui/browsers/annotate.c | 1 + tools/perf/util/alias.c| 1 + tools/perf/util/cache.h| 12 - tools/perf/util/color.c| 1 + tools/perf/util/config.c | 92 +++--- tools/perf/util/config.h | 41 + tools/perf/util/help-unknown-cmd.c | 1 + tools/perf/util/intel-pt.c | 1 + 16 files changed, 111 insertions(+), 75 deletions(-) -- 2.5.0
Re: [PATCH v8 3/5] perf config: Reimplement perf_config() using perf_config_set__it to
Hi, Arnaldo :-D I also discussed this patchset with Namhyung at offline gathering. I sent v9 patchset that contains what Namhyung and you advice me to do. If having your spare time, please review the v9 patchset. If you do, I'd appreciate it :-) Thanks, Taeung On 06/12/2016 05:57 PM, Taeung Song wrote: Hi, Arnaldo What do you think about setting all actual config variables before a sub-command start at perf.c ? (in order to free the config set that contains all configs by perf_config_set__delete() after using it was finished where it was needed) i.e. initialize all actual config variables at perf.c instead of at each source file as below. (before running a particular sub-command at run_builitin()) util/alias.c 22:perf_config(alias_lookup_cb, NULL); util/intel-pt.c 330:perf_config(intel_pt_config_div, &d); 1993:static int intel_pt_perf_config(const char *var, const char *value, void *data) 2047:perf_config(intel_pt_perf_config, pt); util/data-convert-bt.c 1302:perf_config(convert__config, &c); util/help-unknown-cmd.c 62:perf_config(perf_unknown_cmd_config, NULL); builtin-help.c 454:perf_config(perf_help_config, &help_format); perf.c 94:perf_config(pager_command_config, &c); 117:perf_config(browser_command_config, &c); 561:perf_config(perf_default_config, NULL); builtin-record.c 1432:perf_config(perf_record_config, rec); ui/browsers/annotate.c 1163:perf_config(annotate__config, NULL); ui/browser.c 743:perf_config(ui_browser__color_config, NULL); builtin-report.c 829:perf_config(report__config, &report); builtin-kmem.c 1899:perf_config(kmem_config, NULL); builtin-top.c 1231:perf_config(perf_top_config, &top); If we do, we could set all actual config variables before a sub-command work. And the config set that is made by perf_config_set__new() would be reused when we initialize all actual config variables and then if using is is finished, we could free the config set. Thanks, Taeung On 06/10/2016 07:58 PM, Taeung Song wrote: On 06/09/2016 10:34 PM, Arnaldo Carvalho de Melo wrote: Em Wed, Jun 08, 2016 at 09:36:51PM +0900, Taeung Song escreveu: Many sub-commands use perf_config() so everytime perf_config() is called, perf_config() always read config files. (i.e. user config '~/.perfconfig' and system config '$(sysconfdir)/perfconfig') And this is not always a bad thing, think about being in 'mutt' and adding an entry to ~/.mail_aliases, then going to compose a message, would be good that the just added entry to ~/.mail_aliases be considered when adding recipients to your messages, right? In the same fashion, 'perf report', 'perf annotate', 'perf top' are long running utilities that have operations that could get changes to config files without having to restart them, i.e. do annotation changes in your ~/.perfconfig and then see them reflected next time you hit 'A´ to annotate a function in 'perf top' or 'perf report'. Currently, this suggestion isn't already contained among features of perf. right? I understood that you mean while perf process is already running if user change a config file, the changed config can be reflected in 'perf top', 'perf report' or etc without restarting perf process like mutt. Is it right ? So, I think that if tools want ammortize the cost of reading config files, they should create an instance of the relevant object (perf_config_set?) use it and then delete it, but not keep one around for a long time. I got it. How about the two ideas that I have in mind ? 1) If we eliminate the config set object(perf_config_set) after using it because we don't need to keep it until perf process is done, we could bring many codes using perf_config() at one spot of perf.c ? (because it is hard to decide a point of time we destroy the config set.) For example, (This code isn't executable) diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 15982ce..6a56985 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -77,6 +77,23 @@ struct pager_config { int val; }; +static void perf_default_config_init(void) +{ +default_colors_config_init(); +default_annoate_config_init(); +default_report_config_init(); +... +} + +static void perf_config_init(void) +{ +perf_default_config_init(); +colors_config_init(); +annotate_config_init(); +report_config_init(); +... +} + static int pager_command_config(const char *var, const char *value, void *data) { struct pager_config *c = data; @@ -558,7 +575,7 @@ int main(int argc, const char **argv) srandom(time(NULL)); -perf_config(perf_default_config, NULL); +perf_config_init(); set_buildid_dir(NULL); /* get debugfs/tracefs mount point from /proc/mounts */ diff --gi
Re: [PATCH v6 RESEND 4/7] perf config: Use combined {fore,back}ground colors value instead of each two color
Hi, Arnaldo :) On 08/09/2016 03:58 AM, Arnaldo Carvalho de Melo wrote: Em Tue, Aug 02, 2016 at 06:20:46PM +0900, Taeung Song escreveu: To easily set default config values into actual variables for 'colors' config, it would be better that actual variables for each 'colors' config also have only one value like 'default_config_item' type. If we use combined {fore,back}ground colors values in ui_browser_colorset, it smoothly work to initialize default config values for 'colors' config by 'colors_config_items' array that contains default values for it at util/config.c. because both actual variable and config item of 'colors_config_items' are equal in the number of values (as just one). Cc: Namhyung Kim Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Wang Nan Signed-off-by: Taeung Song --- tools/perf/ui/browser.c | 53 +++-- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 3eb3edb..31e2028 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -503,61 +503,53 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *browser) } static struct ui_browser_colorset { - const char *name, *fg, *bg; + const char *name, *colors; int colorset; } ui_browser__colorsets[] = { { .colorset = HE_COLORSET_TOP, .name = "top", - .fg = "red", - .bg = "default", + .colors = "red, default", }, { .colorset = HE_COLORSET_MEDIUM, .name = "medium", - .fg = "green", - .bg = "default", + .colors = "green, default", }, { .colorset = HE_COLORSET_NORMAL, .name = "normal", - .fg = "default", - .bg = "default", + .colors = "default, default", }, { .colorset = HE_COLORSET_SELECTED, .name = "selected", - .fg = "black", - .bg = "yellow", + .colors = "black, yellow", }, { .colorset = HE_COLORSET_JUMP_ARROWS, .name = "jump_arrows", - .fg = "blue", - .bg = "default", + .colors = "blue, default", }, { .colorset = HE_COLORSET_ADDR, .name = "addr", - .fg = "magenta", - .bg = "default", + .colors = "magenta, default", }, { .colorset = HE_COLORSET_ROOT, .name = "root", - .fg = "white", - .bg = "blue", + .colors = "white, blue", }, { .name = NULL, } }; - static int ui_browser__color_config(const char *var, const char *value, void *data __maybe_unused) { - char *fg = NULL, *bg; + char *colors; int i; /* same dir for all commands */ @@ -570,22 +562,18 @@ static int ui_browser__color_config(const char *var, const char *value, if (strcmp(ui_browser__colorsets[i].name, name) != 0) continue; - fg = strdup(value); - if (fg == NULL) - break; + if (strstr(value, ",") == NULL) + return -1; - bg = strchr(fg, ','); - if (bg == NULL) + colors = strdup(value); + if (colors == NULL) break; + ui_browser__colorsets[i].colors = colors; - *bg = '\0'; - while (isspace(*++bg)); - ui_browser__colorsets[i].bg = bg; - ui_browser__colorsets[i].fg = fg; return 0; } - free(fg); + free(colors); return -1; } @@ -743,8 +731,17 @@ void ui_browser__init(void) perf_config(ui_browser__color_config, NULL); while (ui_browser__colorsets[i].name) { + char *colors, *fg, *bg; struct ui_browser_colorset *c = &ui_browser__colorsets[i++]; - sltt_set_color(c->colorset, c->name, c->fg, c->bg); + + colors = strdup(c->colors); + if (fg == NULL) Huh? At this point fb is not even initialized Sorry for my mistake. I'll change 'fg' to 'colors' to handle a exception of strdup(). Thanks, Taeung + break; + fg = strtok(colors, ","); + bg = strtok(NULL, ","); + bg = ltrim(bg); + sltt_set_color(c->colorset, c->name, fg, bg); + free(colors); } annotate_browser__init(); -- 2.5.0
Re: [PATCH v2 1/4] perf annotate stdio: Support --show-nr-samples option
Hi Arnaldo, On 08/18/2017 12:16 AM, Arnaldo Carvalho de Melo wrote: Em Tue, Aug 15, 2017 at 05:06:31PM -0300, Arnaldo Carvalho de Melo escreveu: Em Wed, Aug 16, 2017 at 12:13:09AM +0900, Taeung Song escreveu: Add --show-nr-samples option to perf-annotate so that it corresponds with perf-report. I'll fold the second patch (2/4) with this one, thanks. So, I was going to do that, please do it since there is another thing missing here, document the new option in tools/perf/Documentation/perf-annotate.txt. - Arnaldo Yep, got it, will add the new option --show-nr-samples into Documentation/perf-annotate.txt Thanks, Taeung - Arnaldo Cc: Namhyung Kim Cc: Milian Wolff Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/builtin-annotate.c | 2 ++ tools/perf/util/annotate.c| 6 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 658c920..acde4cc 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -445,6 +445,8 @@ int cmd_annotate(int argc, const char **argv) "Show event group information together"), OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, "Show a column with the sum of periods"), + OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, + "Show a column with the number of samples"), OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode", "'always' (default), 'never' or 'auto' only applicable to --stdio mode", stdio__config_color, "always"), diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 2dab0e5..4397a8b 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1145,6 +1145,9 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st if (symbol_conf.show_total_period) color_fprintf(stdout, color, " %11" PRIu64, sample.period); + else if (symbol_conf.show_nr_samples) + color_fprintf(stdout, color, " %7" PRIu64, + sample.nr_samples); else color_fprintf(stdout, color, " %7.2f", percent); } @@ -1825,7 +1828,8 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, width *= evsel->nr_members; graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples)\n", - width, width, symbol_conf.show_total_period ? "Event count" : "Percent", + width, width, symbol_conf.show_total_period ? "Period" : + symbol_conf.show_nr_samples ? "Samples" : "Percent", d_filename, evsel_name, h->nr_samples); printf("%-*.*s\n", -- 2.7.4
[PATCH v3 0/5] perf annotate: Support --show-nr-samples and circulating view
Hello, Add --show-nr-samples option to perf-annotate so that it corresponds with perf-report. And support the three view based on percent, total period and number of samples on the annotate TUI browser, circulating them like below: Percent -> Period -> Samples -> Percent ... I'd appreciate some feedback on my patchkit. :) The code is available on 'perf/ann-nr-samples-v3' branch at git://github.com/taeung/linux-perf.git Thanks, Taeung v3: - Add --show-nr-samples option in documentation (Arnaldo) - Add a missing --show-total-period in documentation v2: - period and nr-samples view can't be used at the same time (Arnaldo) Taeung Song (5): perf annotate stdio: Support --show-nr-samples option perf annotate: Add a missing period option in documentation perf annotate: Period and samples view can't be used at the same time perf annotate browser: Support --show-nr-samples option perf annotate browser: Circulate percent, total period and samples view tools/perf/Documentation/perf-annotate.txt | 6 ++ tools/perf/builtin-annotate.c | 10 -- tools/perf/ui/browsers/annotate.c | 31 -- tools/perf/util/annotate.c | 6 +- 4 files changed, 44 insertions(+), 9 deletions(-) -- 2.7.4
[PATCH v3 1/5] perf annotate stdio: Support --show-nr-samples option
Add --show-nr-samples option to perf-annotate so that it corresponds with perf-report. Cc: Namhyung Kim Cc: Milian Wolff Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-annotate.txt | 4 tools/perf/builtin-annotate.c | 2 ++ tools/perf/util/annotate.c | 6 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index a89273d..2a5975c 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt @@ -43,6 +43,10 @@ OPTIONS --quiet:: Do not show any message. (Suppress -v) +-n:: +--show-nr-samples:: + Show the number of samples for each symbol + -D:: --dump-raw-trace:: Dump raw trace in ASCII. diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 658c920..acde4cc 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -445,6 +445,8 @@ int cmd_annotate(int argc, const char **argv) "Show event group information together"), OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, "Show a column with the sum of periods"), + OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, + "Show a column with the number of samples"), OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode", "'always' (default), 'never' or 'auto' only applicable to --stdio mode", stdio__config_color, "always"), diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 2dab0e5..4397a8b 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1145,6 +1145,9 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st if (symbol_conf.show_total_period) color_fprintf(stdout, color, " %11" PRIu64, sample.period); + else if (symbol_conf.show_nr_samples) + color_fprintf(stdout, color, " %7" PRIu64, + sample.nr_samples); else color_fprintf(stdout, color, " %7.2f", percent); } @@ -1825,7 +1828,8 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, width *= evsel->nr_members; graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples)\n", - width, width, symbol_conf.show_total_period ? "Event count" : "Percent", + width, width, symbol_conf.show_total_period ? "Period" : + symbol_conf.show_nr_samples ? "Samples" : "Percent", d_filename, evsel_name, h->nr_samples); printf("%-*.*s\n", -- 2.7.4
[PATCH v3 3/5] perf annotate: Period and samples view can't be used at the same time
If users give two options --show-total-period and --show-nr-samples, show their proper usage because the two options can not be used at the same time. Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/builtin-annotate.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index acde4cc..9d25c27 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -403,7 +403,7 @@ int cmd_annotate(int argc, const char **argv) struct perf_data_file file = { .mode = PERF_DATA_MODE_READ, }; - const struct option options[] = { + struct option options[] = { OPT_STRING('i', "input", &input_name, "file", "input file name"), OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", @@ -452,8 +452,12 @@ int cmd_annotate(int argc, const char **argv) stdio__config_color, "always"), OPT_END() }; - int ret = hists__init(); + int ret; + + set_option_flag(options, 0, "show-total-period", PARSE_OPT_EXCLUSIVE); + set_option_flag(options, 0, "show-nr-samples", PARSE_OPT_EXCLUSIVE); + ret = hists__init(); if (ret < 0) return ret; -- 2.7.4
[PATCH v3 5/5] perf annotate browser: Circulate percent, total period and samples view
With a existing 't' hotkey, support the three view based on percent, total period and number of samples on the annotate TUI browser, circulating them like below: Percent -> Period -> Samples -> Percent ... Suggested-by: Namhyung Kim Cc: Milian Wolff Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browsers/annotate.c | 17 ++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index faca1b9..e82e6c5 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -835,7 +835,7 @@ static int annotate_browser__run(struct annotate_browser *browser, "n Search next string\n" "o Toggle disassembler output/simplified view\n" "s Toggle source code view\n" - "t Toggle total period view\n" + "t Circulate percent, total period, samples view\n" "/ Search string\n" "k Toggle line numbers\n" "r Run available scripts\n" @@ -912,8 +912,19 @@ static int annotate_browser__run(struct annotate_browser *browser, } continue; case 't': - annotate_browser__opts.show_total_period = - !annotate_browser__opts.show_total_period; + if (annotate_browser__opts.show_total_period) { + annotate_browser__opts.show_total_period = false; + annotate_browser__opts.show_nr_samples = true; + } else if (annotate_browser__opts.show_nr_samples) + annotate_browser__opts.show_nr_samples = false; + else + annotate_browser__opts.show_total_period = true; + annotate_browser__update_addr_width(browser); + continue; + case 'e': + annotate_browser__opts.show_total_period = false; + annotate_browser__opts.show_nr_samples = + !annotate_browser__opts.show_nr_samples; annotate_browser__update_addr_width(browser); continue; case K_LEFT: -- 2.7.4
[PATCH v3 4/5] perf annotate browser: Support --show-nr-samples option
Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browsers/annotate.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 80f38da..faca1b9 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -42,6 +42,7 @@ static struct annotate_browser_opt { jump_arrows, show_linenr, show_nr_jumps, +show_nr_samples, show_total_period; } annotate_browser__opts = { .use_offset = true, @@ -155,6 +156,9 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int if (annotate_browser__opts.show_total_period) { ui_browser__printf(browser, "%11" PRIu64 " ", bdl->samples[i].he.period); + } else if (annotate_browser__opts.show_nr_samples) { + ui_browser__printf(browser, "%6" PRIu64 " ", + bdl->samples[i].he.nr_samples); } else { ui_browser__printf(browser, "%6.2f ", bdl->samples[i].percent); @@ -167,7 +171,8 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int ui_browser__write_nstring(browser, " ", pcnt_width); else { ui_browser__printf(browser, "%*s", pcnt_width, - annotate_browser__opts.show_total_period ? "Period" : "Percent"); + annotate_browser__opts.show_total_period ? "Period" : + annotate_browser__opts.show_nr_samples ? "Samples" : "Percent"); } } if (ab->have_cycles) { @@ -931,9 +936,11 @@ static int annotate_browser__run(struct annotate_browser *browser, int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, struct hist_browser_timer *hbt) { - /* Set default value for show_total_period. */ + /* Set default value for show_total_period and show_nr_samples */ annotate_browser__opts.show_total_period = - symbol_conf.show_total_period; + symbol_conf.show_total_period; + annotate_browser__opts.show_nr_samples = + symbol_conf.show_nr_samples; return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt); } @@ -1184,6 +1191,7 @@ static struct annotate_config { ANNOTATE_CFG(jump_arrows), ANNOTATE_CFG(show_linenr), ANNOTATE_CFG(show_nr_jumps), + ANNOTATE_CFG(show_nr_samples), ANNOTATE_CFG(show_total_period), ANNOTATE_CFG(use_offset), }; -- 2.7.4
[PATCH v3 2/5] perf annotate: Add a missing period option in documentation
Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-annotate.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index 2a5975c..c635eab 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt @@ -92,6 +92,8 @@ OPTIONS --asm-raw:: Show raw instruction encoding of assembly instructions. +--show-total-period:: Show a column with the sum of periods. + --source:: Interleave source code with assembly code. Enabled by default, disable with --no-source. -- 2.7.4
Re: [PATCH 1/3] perf help: Document missing options
Hi Arnaldo and Namhyung :) On 11/14/2017 09:15 AM, Namhyung Kim wrote: Hi Arnaldo, On Mon, Nov 13, 2017 at 03:29:56PM -0300, Arnaldo Carvalho de Melo wrote: Em Sun, Nov 12, 2017 at 10:10:45AM +0900, Sihyeon Jang escreveu: Cc: Jiri Olsa Cc: Namhyung Kim Signed-off-by: Sihyeon Jang --- tools/perf/Documentation/perf-help.txt | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-help.txt b/tools/perf/Documentation/perf-help.txt index 5143918..bb605af 100644 --- a/tools/perf/Documentation/perf-help.txt +++ b/tools/perf/Documentation/perf-help.txt @@ -7,7 +7,7 @@ perf-help - display help information about perf SYNOPSIS -'perf help' [-a|--all] [COMMAND] +'perf help' [--all] [--man|--web|--info] [COMMAND] Can you try figuring out if this actually works? I tried here and it doesn't, its an area we took "for free" when we copied the initial codebase from git.git, but I never looked at this area that much, now that I try: Yeah, I'm not sure we need to keep it. [acme@jouet linux]$ perf help Config with no key for man viewer: childrenError: wrong config key-value pair top.children=true [acme@jouet linux]$ Unsure if this is something that got broken by the 'perf config' patches, Taeung? Looks like a bug in 8e99b6d4533c ("tools include: Adopt strstarts() from the kernel"). Following patch should fix it: Thanks, Namhyung I also checked this error and test the below patch. It seems that Namhyung already fixes it !! Thanks, Taeung From 096b78b437b5758acc025498e88d73d9d471b3c0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 14 Nov 2017 09:10:43 +0900 Subject: [PATCH] perf help: Fix a bug during strstart() conversion The commit 8e99b6d4533c changed prefixcmp() to strstart() but missed to change the return value in some place. It makes perf help print annoying output even for sane config items like below: $ perf help '.root': unsupported man viewer sub key. ... Fixes: 8e99b6d4533c ("tools include: Adopt strstarts() from the kernel") Cc: Taeung Song Signed-off-by: Namhyung Kim --- tools/perf/builtin-help.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index dbe4e4153bcf..ff51e5fc0daf 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c @@ -283,7 +283,7 @@ static int perf_help_config(const char *var, const char *value, void *cb) add_man_viewer(value); return 0; } - if (!strstarts(var, "man.")) + if (strstarts(var, "man.")) return add_man_viewer_info(var, value); return 0; @@ -313,7 +313,7 @@ static const char *cmd_to_page(const char *perf_cmd) if (!perf_cmd) return "perf"; - else if (!strstarts(perf_cmd, "perf")) + else if (strstarts(perf_cmd, "perf")) return perf_cmd; return asprintf(&s, "perf-%s", perf_cmd) < 0 ? NULL : s;
Re: [PATCH 2/3] perf top: Support call-graph display options also
Hi, Namhyung and Ingo > On Oct 22, 2015, at 9:20 PM, Namhyung Kim wrote: > > On Thu, Oct 22, 2015 at 5:23 PM, Ingo Molnar wrote: >> >> * Namhyung Kim wrote: >> >>> Currently 'perf top --call-graph' option is same as 'perf record'. But >>> 'perf top' also need to receive display options in 'perf report'. To do >>> that, change parse_callchain_report_opt() to allow record options too. >>> >>> Now perf top can receive display options like below: >>> >>> $ perf top --call-graph >>>Error: option `call-graph' requires a value >>> >>> Usage: perf top [] >>> >>>--call-graph >>> >>> >>> setup and enables call-graph (stack chain/backtrace) >>> recording: fp dwarf lbr, output_type (graph, flat, >>> fractal, or none), min percent threshold, optional >>> print limit, callchain order, key (function or >>> address), add branches >> >> Yeah, so this fix is nice, and I think we should also do another patch to >> fix the >> help text output to be the following: >> >> --call-graph >> >> >> >> Set up and enable call graph (call chain, stack backtrace) >> recording: >> >> record_mode: call graph recording mode (fp|dwarf|lbr) >> record_size: if rec_mode == dwarf, maximum depth of stack >> recording (bytes), >>default: 8192 bytes. >> print_style: call graph printing style >> (graph|flat|fractal|none) >> limit: minimum call graph inclusion threshold >> (percent) >> print_limit: printing threshold (percent) >> call_order:call graph order (caller|callee) >> sort_key: sorting key (function|address|branch) >> >> Default: fp,graph,0.5,0.0,caller,function >> >> Note that this text evolved a bit over what I sent in my previous mail. > > OK. I'll cook a patch to improve help message like this as well as man page. > > >> >> Also note that I think we should sync up the perf config options to be the >> same as >> the option name shortcuts used in this help text. > > Ah, good idea. > >> >> Side note: to improve perf config usability, we should probably also >> recognize >> underscores in perf config entries, i.e. the following variants should both >> work: >> >>print_percent = 1 >>print-percent = 1 >> >> Right now only the second one will match. > > Taeung, could you consider fixing this in your config patchiest? > Sure, no problem. I thought as below. Even if one use a print_percent variable, it will be handled like print-percent. Also if a user change print_percent variable by perf-config command, print-percent variable will remain in perfconfig file. (Because perf-config command will rewrite perfconfig file.) Is anything wrong ? Thanks, Taeung -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v1] perf report: Fix owner error when reading perf.data
If perf.data file is owned by some user, it can't be read even if current user is root. A 'st_uid' from fstat() is user ID of the file owner. Therefore use getuid() instead of st_uid to check if user of the calling 'perf' process is root or not. Signed-off-by: Taeung Song --- tools/perf/util/data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 1921942..91ebe4e 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -67,7 +67,7 @@ static int open_file_read(struct perf_data_file *file) if (fstat(fd, &st) < 0) goto out_close; - if (!file->force && st.st_uid && (st.st_uid != geteuid())) { + if (!file->force && getuid() && (st.st_uid != geteuid())) { pr_err("File %s not owned by current user or root (use -f to override)\n", file->path); goto out_close; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v1] perf report: Fix owner error when reading perf.data
> On Oct 1, 2015, at 6:10 PM, Ingo Molnar wrote: > > > * Taeung Song wrote: > >> If perf.data file is owned by some user, >> it can't be read even if current user is root. > > That's intentional: to keep a malicious local user from passing a perf.data > to > root who does 'perf report' accidentally or in the wrong directory. > > root can copy or chown it to himself - or we could add some --really-force > flag > for that. I got it. I didn’t know its intention. Thanks, Taeung > > Thanks, > > Ingo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v7 0/7] perf tools: Add 'perf-config' command
So far, it is difficult that the state of perf configs is looked through and there's no knowing what kind of other variables except variables in perfconfig.example. Also perf configs can't be changed without manually modifying $HOME/.perfconfig or $(sysconfdir)/perfconfig file. So I suggest this patchset of the perf-config command which can list, get, set, remove perf configs or list with default config values as below. Taeung Song (7): [PATCH v7 1/7] perf tools: Add 'perf-config' command [PATCH v7 2/7] perf config: Add '--system' and '--user' options to select which config file is used [PATCH v7 3/7] perf config: Add a option 'list-all' to perf-config [PATCH v7 4/7] perf config: Add 'get' functionality [PATCH v7 5/7] perf config: Add 'set' feature [PATCH v7 6/7] perf config: normalize a value depending on default type of it [PATCH v7 7/7] perf config: Add a option 'remove' to perf-config Changes in v7: - Modify explanations of syntax and options(color, gtk, tui, buildid, annotate) to be better proper descriptions as suggested by Arnaldo (PATCH v7 1/7) Changes in v6: - Split a 'set' feature patch into two patch to separate normalize_value() from it. (PATCH v6 5/7, PATCH v6 6/7) - 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.) (PATCH v6 5/7, PATCH v6 7/7) Changes in v5: - Simplify the switch statement in cmd_config() - Set a config file path with '--system' or '--user' instead of '--global' or '--system' as suggested by Namhyung. (PATCH v5 2/6) - The patch about 'get' and 'set 'split into two patchs as suggested by Namhyung. (PATCH v5 4/6, PATCH v5 5/6) Changes in v4: - If some config value is default value, notice it is '(default)' as suggested by Jirka. (PATCH v4 3/5) - If there wasn't any perfconfig file, perf-config malfunctioned like Jirka pointed out. So add exception routine with '--global' and '--system' option which can select perf config file path. (PATCH v4 2/5) Changes in v3: - Add a config variable 'kmem.default' with a default value as suggested by Namhyung. (PATCH v3 2/5, PATCH v4 3/5) Changes in v2: - Change option name of listing all configs as '--list-all' instead of '--all' as suggested by Namhyung. (PATCH v2 3/4, PATCH v4 4/5) - Correct small infelicities or typing errors in a perf-config documention as suggested by Arnaldo. (PATCH v2 1/4, PATCH v4 1/5) - Declaration a global variable 'static struct default_configsets' has config variables with default values instead of using a 'util/PERFCONFIG-DEFAULT' file. (PATCH v2 3/4, PATCH v4 3/5) - Add a function to normalize a value and check data type of it. (PATCH v2 2/4, PATCH v4 3/5) - 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. (PATCH v2 2/4, PATCH v4 3/5) - If run perf-config command without any option, perf-config work as '--list'. (PATCH v2 1/4, PATCH v4 1/5) tools/perf/Build | 1 + tools/perf/Documentation/perf-config.txt | 422 + tools/perf/builtin-config.c | 769 +++ tools/perf/builtin.h | 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c| 1 + tools/perf/util/cache.h | 18 + tools/perf/util/config.c | 31 +- 8 files changed, 1242 insertions(+), 2 deletions(-) create mode 100644 tools/perf/Documentation/perf-config.txt create mode 100644 tools/perf/builtin-config.c -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v7 7/7] perf config: Add a option 'remove' to perf-config
A option 'remove' is to remove specific config variables. For the syntax examples, # perf config [] -r | --remove [section.name ...] Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 6 + tools/perf/builtin-config.c | 38 ++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index f24926e..281e759 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -13,6 +13,8 @@ or 'perf config' [] -l | --list or 'perf config' [] -a | --list-all +or +'perf config' [] -r | --remove [section.name ...] DESCRIPTION --- @@ -37,6 +39,10 @@ OPTIONS --list-all:: Show current and all possible config variables with default values. +-r:: +--remove:: + Remove specific config variables. + CONFIGURATION FILE -- diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 680a655..9253eae 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_REMOVE } actions; static struct option config_options[] = { @@ -35,6 +36,8 @@ 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('r', "remove", &actions, +"remove specific variables: [section.name ...]", ACTION_REMOVE), OPT_END() }; @@ -532,7 +535,14 @@ static int set_config(struct list_head *sections, const char *config_file_name, struct config_element *element = NULL; find_config(sections, §ion, &element, section_name, name); - if (value != NULL) { + if (!value) { + /* value == NULL means remove the variable */ + if (section && element) { + if (!element->value) + free(element->value); + element->value = NULL; + } + } else { value = normalize_value(section_name, name, value); /* if there isn't existent section, add a new section */ @@ -659,6 +669,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); @@ -690,6 +701,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_file_name, + argv[i], NULL); + } + } else { + pr_err("Error: Missing arguments\n"); + parse_options_usage(config_usage, config_options, "r", 1); + return -1; + } + 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 majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v7 6/7] perf config: normalize a value depending on default type of it
Whether or not user mis-type wrong data type to set config, normalize the value. If a config user enter isn't contained in default configs, just pass as it is. For the examples, # perf config report.queue-size=1M # perf config report.queue-size report.queue-size=1048576 Signed-off-by: Taeung Song --- tools/perf/builtin-config.c | 48 - 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index f034c19..680a655 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -483,6 +483,48 @@ 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 key[BUFSIZ]; + char *normalized; + + scnprintf(key, sizeof(key), "%s.%s", section_name, name); + for (i = 0; default_configsets[i].section_name != NULL; i++) { + struct default_configset *config = &default_configsets[i]; + + if (!strcmp(config->section_name, section_name) + && !strcmp(config->name, name)) { + if (!config->type) + ret = asprintf(&normalized, "%s", value); + else if (!strcmp(config->type, TYPE_BOOL)) + ret = asprintf(&normalized, "%s", + perf_config_bool(key, value) ? "true" : "false"); + else if (!strcmp(config->type, TYPE_INT)) + ret = asprintf(&normalized, "%d", + perf_config_int(key, value)); + else if (!strcmp(config->type, TYPE_LONG)) + ret = asprintf(&normalized, "%"PRId64, + perf_config_u64(key, value)); + else if (!strcmp(config->type, TYPE_DIRNAME)) + ret = asprintf(&normalized, "%s", + perf_config_dirname(key, 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) { @@ -491,11 +533,7 @@ static int set_config(struct list_head *sections, const char *config_file_name, find_config(sections, §ion, &element, section_name, name); if (value != NULL) { - value = strdup(value); - if (!value) { - pr_err("%s: strdup failed\n", __func__); - return -1; - } + value = normalize_value(section_name, name, value); /* if there isn't existent section, add a new section */ if (!section) { -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v7 1/7] perf tools: Add 'perf-config' command
The perf configuration file contains many variables which can make the perf command's action more effective. 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 and a document for it. perf config [options] display current perf config variables. # perf config or # perf config -l | --list Signed-off-by: Taeung Song --- tools/perf/Build | 1 + tools/perf/Documentation/perf-config.txt | 396 +++ tools/perf/builtin-config.c | 62 + tools/perf/builtin.h | 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c| 1 + 6 files changed, 462 insertions(+) create mode 100644 tools/perf/Documentation/perf-config.txt 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/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt new file mode 100644 index 000..e8013b3 --- /dev/null +++ b/tools/perf/Documentation/perf-config.txt @@ -0,0 +1,396 @@ +perf-config(1) +== + +NAME + +perf-config - Get and set variables in a configuration file. + +SYNOPSIS + +[verse] +'perf config' -l | --list + +DESCRIPTION +--- +You can manage variables in a configuration file with this command. + +OPTIONS +--- + +-l:: +--list:: + Show current config variables, name and value, for all sections. + +CONFIGURATION FILE +-- + +The Perf configuration file contains many variables which can make +the perf command's action more effective. +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. + +The variables are divided into sections. In each section, the variables +that are composed of a name and value. + +Syntax +~~ + +The file consist of sections. A section starts with its name +surrounded by square brackets and continues till the next section +begins. Each variable belong to a section, which means that +there must be a section header before the first variable, as below: +Each variable are in the form 'name = value'. + + [section] + name1 = value1 + name2 = value2 + +Section names are case sensitive and can contain any characters except +newline (double quote `"` and backslash have to be escaped as `\"` and `\\`, +respectively). Section headers can't span multiple lines. + +Example +~~~ + +Given a $HOME/.perfconfig like this: + +# +# This is the config file, and +# a '#' and ';' character indicates a comment +# + +[colors] + # Color variables + top = red, default + medium = green, default + normal = lightgray, default + selected = white, lightgray + code = blue, default + addr = magenta, default + root = white, blue + +[tui] + # Defaults if linked with libslang + report = on + annotate = on + top = on + +[buildid] + # Default, disable using /dev/null + dir = ~/.debug + +[annotate] + # Defaults + hide_src_code = false + use_offset = true + jump_arrows = true + show_nr_jumps = false + +[help] + # Format can be man, info, web or html + format = man + autocorrect = 0 + +[ui] + show-headers= true + +[call-graph] + # fp (framepointer), dwarf + record-mode = fp + print-type = graph + order = caller + sort-key = function + +Variables +~ + +colors.*:: + Color variables can customize colors of the output which is printed out + from ‘report’, ‘top’, ’annotate’ on tui. + Color variables are composed of foreground and background + and should have two values, comma separated as below. + + medium = green, lightgray + + If you want to keep the background or the foregroud color set for your + terminal, replace the desired value with 'default'. For instance: + + medium = default, default + + Available colors: + red, green, default, black, blue, white, magenta, lightgray + + colors.top:: + ‘top’ means a overhead percentage which is more than 5%. + And values of this variable specify colors of percentage. + Basic key values are foreground-color ’red’ and + backgrou
[PATCH v7 2/7] perf config: Add '--system' and '--user' options to select which config file is used
Which config file is used is decided in only perf_config(). And a perf-config command depend on perf_config() to list config variables with values. So add '--system' and '--user' options to select which config file to be used without perf_config(). 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 but user config have priority. The syntax examples are like below perf config [] [options] a specific config file. # perf config --user | --system or both user and system config file. # perf config In addition, use List data structure which has config info. Because perf_config() isn't used any more and directly collect config info by perf_config_from_file() with a specific config file path. Whichever config file or both are used, list is required to keep and handle config variables and values. Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 14 ++- tools/perf/builtin-config.c | 163 +-- tools/perf/util/cache.h | 15 +++ tools/perf/util/config.c | 4 +- 4 files changed, 187 insertions(+), 9 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index e8013b3..a42d409 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' [] -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 -- @@ -33,6 +41,10 @@ store a system-wide default configuration. The variables are divided into sections. In each section, the variables that are composed of a name and value. +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 30b1500..92be3eb 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 [] [options]", NULL }; @@ -23,19 +25,150 @@ enum actions { } actions; static struct option config_options[] = { + OPT_GROUP("Config file location"), + OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"), + OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"), OPT_GROUP("Action"), OPT_SET_UINT('l', "list", &actions, "show current config variables", ACTION_LIST), OPT_END() }; +static int show_config(struct list_head *sections) +{ + struct config_section *section; + struct config_element *element; + + list_for_each_entry(section, sections, list) { + list_for_each_entry(element, §ion->element_head, list) { + printf("%s.%s=%s\n", section->name, + element->name, element->value); + } + } + + return 0; +} -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, §ion->element_head, list) + if (!strcmp(element->name, name)) + return element; + + return NULL; +} + +static void find_config(struct list_head *sections, +
[PATCH v7 4/7] perf config: Add 'get' functionality
This patch consists of functions which can get specific config variables. For the syntax examples, perf config [] [section.name ...] display key-value pairs of specific config variables # perf config report.queue-size report.children Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 2 + tools/perf/builtin-config.c | 75 ++-- tools/perf/util/cache.h | 1 + 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 15fbbd9..7b83406 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' [] [section.name ...] +or 'perf config' [] -l | --list or 'perf config' [] -a | --list-all diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 8e16e18..731056c 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 [] [options]", + "perf config [] [options] [section.name ...]", NULL }; @@ -452,6 +452,35 @@ 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, §ion, &element, section_name, name); + + if (section && element) { + printf("%s.%s=%s\n", section->name, + element->name, element->value); + return 0; + } + + for (i = 0; default_configsets[i].section_name != NULL; i++) { + struct default_configset *config = &default_configsets[i]; + + if (!strcmp(config->section_name, section_name) && + !strcmp(config->name, name)) { + printf("%s.%s=%s (default)\n", config->section_name, + config->name, config->value); + return 0; + } + } + + return -1; +} + static int collect_current_config(const char *var, const char *value, void *spec_sections __maybe_unused) { @@ -497,9 +526,42 @@ static int collect_current_config(const char *var, const char *value, return 0; } +static int perf_configset_with_option(configset_fn_t fn, struct list_head *sections, + const char *var) +{ + char *section_name; + char *name; + const char *last_dot; + char *key = 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); + return -1; + } + if (!last_dot[1]) { + pr_err("The config varible does not contain variable name: %s\n", key); + return -1; + } + + section_name = strsep(&key, "."); + name = strsep(&key, "."); + free(key); + + return fn(sections, section_name, name); +} + int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) { - int ret = 0; + int i, ret = 0; struct list_head sections; const char *system_config = perf_etc_perfconfig(); char *user_config = mkpath("%s/.perfconfig", getenv("HOME")); @@ -532,7 +594,6 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) break; } case ACTION_LIST: - default: if (argc) { pr_err("Error: takes no arguments\n"); if (actions == ACTION_LIST_ALL) @@ -540,7 +601,13 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) else parse_options_usage(config_usage, config_options, "l", 1); return -1; - } else + } + default: + if (argc) + for (i = 0; argv[i]; i++
[PATCH v7 5/7] perf config: Add 'set' feature
This patch consists of functions which can set specific config variables. For the syntax examples, perf config [] [options] [section.name[=value] ...] set specific config variables # perf config report.queue-size=100M report.children=true Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 2 +- tools/perf/builtin-config.c | 122 ++- tools/perf/util/cache.h | 4 +- tools/perf/util/config.c | 27 +++ 4 files changed, 133 insertions(+), 22 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 7b83406..f24926e 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' [] [section.name ...] +'perf config' [] [section.name[=value] ...] or 'perf config' [] -l | --list or diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 731056c..f034c19 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 [] [options] [section.name ...]", + "perf config [] [options] [section.name[=value] ...]", NULL }; @@ -453,7 +453,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 __maybe_unused) { int i; struct config_section *section = NULL; @@ -481,6 +483,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, §ion, &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(§ion->list, sections); + } + /* if nothing to replace, add a new element which contains key-value pair. */ + if (!element) { + add_element(§ion->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 __maybe_unused) { @@ -526,8 +561,10 @@ static int collect_current_config(const char *var, const char *value, return 0; } -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) { char *section_name; char *name; @@ -554,15 +591,31 @@ static int perf_configset_with_option(configset_fn_t fn, struct list_head *secti section_name = strsep(&key, "."); name = strsep(&key, "."); + if (!value) { + /* do nothing */ + } else if (!strcmp(value, "=")) { + pr_err("The config variable does not contain a value: %s.%s\n", + section_name, name); + return -1; + } else { + value++; + name = strsep(&name, "="); + if (name[0] == '\0') { + pr_err("invalid key: %s\n", var); + return -1; + } + } free(key); - return fn(sections, section_name, name); + return fn(sections, config_file_name, section_na
[PATCH v7 3/7] perf config: Add a option 'list-all' to perf-config
A option 'list-all' is to display both current config variables and all possible config variables with default values. The syntax examples are like below perf config [] [options] display all perf config with default values. # perf config -a | --list-all Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 6 + tools/perf/builtin-config.c | 339 ++- 2 files changed, 343 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index a42d409..15fbbd9 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -9,6 +9,8 @@ SYNOPSIS [verse] 'perf config' [] -l | --list +or +'perf config' [] -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 92be3eb..8e16e18 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -21,7 +21,8 @@ static const char * const config_usage[] = { }; enum actions { - ACTION_LIST = 1 + ACTION_LIST = 1, + ACTION_LIST_ALL } actions; static struct option config_options[] = { @@ -31,8 +32,292 @@ static struct option config_options[] = { OPT_GROUP("Action"), 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_END() }; + +/* section names */ +#define COLORS "colors" +#define TUI "tui" +#define BUILDID "buildid" +#define ANNOTATE "annotate" +#define GTK "gtk" +#define PAGER "pager" +#define HELP "help" +#define HIST "hist" +#define UI "ui" +#define CALL_GRAPH "call-graph" +#define REPORT "report" +#define TOP "top" +#define MAN "man" +#define KMEM "kmem" + +/* config variable types */ +#define TYPE_INT "int" +#define TYPE_LONG "long" +#define TYPE_DIRNAME "dirname" +#define TYPE_BOOL "bool" + +static struct default_configset { + const char *section_name; + const char *name, *value, *type; + +} default_configsets[] = { + { + .section_name = COLORS, + .name = "top", + .value = "red, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "medium", + .value = "green, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "normal", + .value = "lightgray, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "selected", + .value = "white, lightgray", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "code", + .value = "blue, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "addr", + .value = "magenta, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "root", + .value = "white, blue", + .type = NULL, + }, + { + .section_name = TUI, + .name = "report", + .value = "true", + .type = TYPE_BOOL, + }, + { + .section_name = TUI, + .name = "annotate", + .value = "true", + .type = TYPE_BOOL, + }, + { + .section_name = TUI, + .name = "top", + .value = "true", + .type = TYPE_BOOL, + }, + { + .section_name = BUILDID, + .name = "dir", + .value = "~/.debug", + .type = TYPE_DIRNAME, + }, + { + .section_name = ANNOTATE, + .name = "hide_src_code", +
[PATCH v2 2/2] tools/bpftool: Fix segfault case regarding 'pin' arguments
Arguments of 'pin' subcommand should be checked at the very beginning of do_pin_any(). Otherwise segfault errors can occur when using 'map pin' or 'prog pin' commands, so fix it. # bpftool prog pin id Segmentation fault Fixes: 71bb428fe2c1 ("tools: bpf: add bpftool") Reviewed-by: Jakub Kicinski Reported-by: Taehee Yoo Signed-off-by: Taeung Song --- tools/bpf/bpftool/common.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 32f9e397a6c0..3f140eff039f 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -217,6 +217,14 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) int err; int fd; + if (argc < 3) { + p_err("too few arguments, id ID and FILE path is required"); + return -1; + } else if (argc > 3) { + p_err("too many arguments"); + return -1; + } + if (!is_prefix(*argv, "id")) { p_err("expected 'id' got %s", *argv); return -1; @@ -230,9 +238,6 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) } NEXT_ARG(); - if (argc != 1) - usage(); - fd = get_fd_by_id(id); if (fd < 0) { p_err("can't get prog by id (%u): %s", id, strerror(errno)); -- 2.17.1
[PATCH bpf-next] tools/bpftool: ignore build products
For untracked things of tools/bpf, add this. Reviewed-by: Quentin Monnet Signed-off-by: Taeung Song --- tools/bpf/.gitignore | 5 + tools/bpf/bpftool/.gitignore | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 tools/bpf/.gitignore diff --git a/tools/bpf/.gitignore b/tools/bpf/.gitignore new file mode 100644 index ..dfe2bd5a4b95 --- /dev/null +++ b/tools/bpf/.gitignore @@ -0,0 +1,5 @@ +FEATURE-DUMP.bpf +bpf_asm +bpf_dbg +bpf_exp.yacc.* +bpf_jit_disasm diff --git a/tools/bpf/bpftool/.gitignore b/tools/bpf/bpftool/.gitignore index d7e678c2d396..67167e44b726 100644 --- a/tools/bpf/bpftool/.gitignore +++ b/tools/bpf/bpftool/.gitignore @@ -1,3 +1,5 @@ *.d bpftool +bpftool*.8 +bpf-helpers.* FEATURE-DUMP.bpftool -- 2.17.1
[PATCH v2 bpf-next] tools/bpftool: ignore build products
For untracked things of tools/bpf, add this. Reviewed-by: Jakub Kicinski Signed-off-by: Taeung Song --- tools/bpf/.gitignore | 5 + tools/bpf/bpftool/.gitignore | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 tools/bpf/.gitignore diff --git a/tools/bpf/.gitignore b/tools/bpf/.gitignore new file mode 100644 index ..dfe2bd5a4b95 --- /dev/null +++ b/tools/bpf/.gitignore @@ -0,0 +1,5 @@ +FEATURE-DUMP.bpf +bpf_asm +bpf_dbg +bpf_exp.yacc.* +bpf_jit_disasm diff --git a/tools/bpf/bpftool/.gitignore b/tools/bpf/bpftool/.gitignore index d7e678c2d396..67167e44b726 100644 --- a/tools/bpf/bpftool/.gitignore +++ b/tools/bpf/bpftool/.gitignore @@ -1,3 +1,5 @@ *.d bpftool +bpftool*.8 +bpf-helpers.* FEATURE-DUMP.bpftool -- 2.17.1
[PATCH] samples/bpf: Add BTF build flags to Makefile
To smoothly test BTF supported binary on samples/bpf, let samples/bpf/Makefile probe llc, pahole and llvm-objcopy for BPF support and use them like tools/testing/selftests/bpf/Makefile changed from the commit c0fa1b6c3efc ("bpf: btf: Add BTF tests") Cc: Martin KaFai Lau Signed-off-by: Taeung Song --- samples/bpf/Makefile | 21 - 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 1303af10e54d..e079266360a3 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -191,6 +191,8 @@ HOSTLOADLIBES_xdpsock += -pthread # make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang LLC ?= llc CLANG ?= clang +LLVM_OBJCOPY ?= llvm-objcopy +BTF_PAHOLE ?= pahole # Detect that we're cross compiling and use the cross compiler ifdef CROSS_COMPILE @@ -198,6 +200,20 @@ HOSTCC = $(CROSS_COMPILE)gcc CLANG_ARCH_ARGS = -target $(ARCH) endif +BTF_LLC_PROBE := $(shell $(LLC) -march=bpf -mattr=help 2>&1 | grep dwarfris) +BTF_PAHOLE_PROBE := $(shell $(BTF_PAHOLE) --help 2>&1 | grep BTF) +BTF_OBJCOPY_PROBE := $(shell $(LLVM_OBJCOPY) --help 2>&1 | grep -i 'usage.*llvm') + +ifneq ($(BTF_LLC_PROBE),) +ifneq ($(BTF_PAHOLE_PROBE),) +ifneq ($(BTF_OBJCOPY_PROBE),) + EXTRA_CFLAGS += -g + LLC_FLAGS += -mattr=dwarfris + DWARF2BTF = y +endif +endif +endif + # Trick to allow make to be run from this directory all: $(MAKE) -C ../../ $(CURDIR)/ BPF_SAMPLES_PATH=$(CURDIR) @@ -256,4 +272,7 @@ $(obj)/%.o: $(src)/%.c -Wno-gnu-variable-sized-type-not-at-end \ -Wno-address-of-packed-member -Wno-tautological-compare \ -Wno-unknown-warning-option $(CLANG_ARCH_ARGS) \ - -O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $@ + -O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf $(LLC_FLAGS) -filetype=obj -o $@ +ifeq ($(DWARF2BTF),y) + $(BTF_PAHOLE) -J $@ +endif -- 2.17.1
[Question] bpf: about a new 'tools/bpf/bpf_dwarf2btf'
Hi, Building bpf programs with .BTF section, I thought it'd be better to convert dwarf info to .BTF by a new tool such as 'tools/bpf/bpf_dwarf2btf' instead of pahole in the future. Currently for bpf binary that have .BTF section, we need to use pahole from https://github.com/iamkafai/pahole/tree/btf with the command line such as "pahole -J bpf_prog.o". I think it is great but if implementing new 'bpf_dwarf2btf' (dwarf parsing + btf encoder code written by Martin KaFai Lau on the pahole project i.e. btf.h, btf_encoder.c, btf_encoder.h, libbtf.c, libbtf.h), BPF developers would more easily use functionalities based on BTF. What do you think about this ? Do you think this is needed ? Or, already implementing something like this ? If it is needed, I want to try to make 'tools/bpf/bpf_dwarf2btf' based on the pahole code. I'd appreciate it, if you reply to this Thanks, Taeung
Re: pahole + BTF was: Re: [Question] bpf: about a new 'tools/bpf/bpf_dwarf2btf'
Hi Arnaldo, On 07/26/2018 02:52 AM, Arnaldo Carvalho de Melo wrote: Em Thu, Jul 26, 2018 at 02:23:32AM +0900, Taeung Song escreveu: Hi, Building bpf programs with .BTF section, I thought it'd be better to convert dwarf info to .BTF by a new tool such as 'tools/bpf/bpf_dwarf2btf' instead of pahole in the future. Currently for bpf binary that have .BTF section, we need to use pahole from https://github.com/iamkafai/pahole/tree/btf with the command line such as "pahole -J bpf_prog.o". I think it is great but if implementing new 'bpf_dwarf2btf' (dwarf parsing + btf encoder code written by Martin KaFai Lau on the pahole project i.e. btf.h, btf_encoder.c, btf_encoder.h, libbtf.c, libbtf.h), BPF developers would more easily use functionalities based on BTF. What would be easier exactly? Not having to install a package but build it from the kernel sources? Many kernel developers already have pahole installed for other uses, so no need to install anything. Understood, but I think there are many non-kernel developers developing BPF programs and they mightn't have or use pahole. So, if providing the 'dwarf2btf' feature on tools/bpf or tools/bpf/bpftool, non-kernel developers can also more easily build bpf prog with .BPF, no ? BTW, Daniel, I just pushed to pahole's main repository at: git://git.kernel.org/pub/scm/devel/pahole/pahole.git with the Martin's BTF patch, so no need to pull from the github one, I'll tag v1.12 and announce the release so that distro package maintainers can update their packages. What do you think about this ? Do you think this is needed ? Or, already implementing something like this ? If it is needed, I want to try to make 'tools/bpf/bpf_dwarf2btf' based on the pahole code. I'd appreciate it, if you reply to this The way Martin took advantage of the work done a long time ago to support CTF out of the same DWARF reading codebase was really cool, not that much work to do, just add a new format to pahole's codebase making it more useful. I got it ! Thanks, Taeung I was just so far overly picky with testing it and kept leaving for later to have a good documentation about testing it, vacation and perf maintainership duties kept making this take like forever, grumble :-\ - Arnaldo -- oh.. :'(
Re: pahole + BTF was: Re: [Question] bpf: about a new 'tools/bpf/bpf_dwarf2btf'
On 07/26/2018 03:27 AM, Taeung Song wrote: Hi Arnaldo, On 07/26/2018 02:52 AM, Arnaldo Carvalho de Melo wrote: Em Thu, Jul 26, 2018 at 02:23:32AM +0900, Taeung Song escreveu: Hi, Building bpf programs with .BTF section, I thought it'd be better to convert dwarf info to .BTF by a new tool such as 'tools/bpf/bpf_dwarf2btf' instead of pahole in the future. Currently for bpf binary that have .BTF section, we need to use pahole from https://github.com/iamkafai/pahole/tree/btf with the command line such as "pahole -J bpf_prog.o". I think it is great but if implementing new 'bpf_dwarf2btf' (dwarf parsing + btf encoder code written by Martin KaFai Lau on the pahole project i.e. btf.h, btf_encoder.c, btf_encoder.h, libbtf.c, libbtf.h), BPF developers would more easily use functionalities based on BTF. What would be easier exactly? Not having to install a package but build it from the kernel sources? Many kernel developers already have pahole installed for other uses, so no need to install anything. Understood, but I think there are many non-kernel developers developing BPF programs and they mightn't have or use pahole. So, if providing the 'dwarf2btf' feature on tools/bpf or tools/bpf/bpftool, non-kernel developers can also more easily build bpf prog with .BPF, no ? Or, if tools/lib/bpf/ have the 'dwarf2btf' feature, I think BPF developers can just use bpf programs that have dwarf info after compiling with clang '-g' and llc '-mattr=dwarfris', even though not using pahole. Isn't it good way ? BTW, Daniel, I just pushed to pahole's main repository at: git://git.kernel.org/pub/scm/devel/pahole/pahole.git with the Martin's BTF patch, so no need to pull from the github one, I'll tag v1.12 and announce the release so that distro package maintainers can update their packages. What do you think about this ? Do you think this is needed ? Or, already implementing something like this ? If it is needed, I want to try to make 'tools/bpf/bpf_dwarf2btf' based on the pahole code. I'd appreciate it, if you reply to this The way Martin took advantage of the work done a long time ago to support CTF out of the same DWARF reading codebase was really cool, not that much work to do, just add a new format to pahole's codebase making it more useful. I got it ! Thanks, Taeung I was just so far overly picky with testing it and kept leaving for later to have a good documentation about testing it, vacation and perf maintainership duties kept making this take like forever, grumble :-\ - Arnaldo -- oh.. :'(
Re: [PATCH 09/10] lib traceeevent: Fix missing break in FALSE case of pevent_filter_clear_trivial()
Hi Steven, I found a trivial typo "eee" on the commit log title It seems better to change "lib traceeevent" to " lib traceevent", if you want to do it.. Thanks, Taeung On 01/12/2018 09:47 AM, Steven Rostedt wrote:
[PATCH v2 2/4] samples/bpf: Check the result of system()
To avoid the below build warning message, use new generate_load() checking the return value. ignoring return value of ‘system’, declared with attribute warn_unused_result And it also refactors the duplicate code of both test_perf_event_all_cpu() and test_perf_event_task() Cc: Teng Qin Signed-off-by: Taeung Song --- samples/bpf/trace_event_user.c | 27 --- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/samples/bpf/trace_event_user.c b/samples/bpf/trace_event_user.c index 1fa1becfa641..d08046ab81f0 100644 --- a/samples/bpf/trace_event_user.c +++ b/samples/bpf/trace_event_user.c @@ -122,6 +122,16 @@ static void print_stacks(void) } } +static inline int generate_load(void) +{ + if (system("dd if=/dev/zero of=/dev/null count=5000k status=none") < 0) { + printf("failed to generate some load with dd: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + static void test_perf_event_all_cpu(struct perf_event_attr *attr) { int nr_cpus = sysconf(_SC_NPROCESSORS_CONF); @@ -142,7 +152,11 @@ static void test_perf_event_all_cpu(struct perf_event_attr *attr) assert(ioctl(pmu_fd[i], PERF_EVENT_IOC_SET_BPF, prog_fd[0]) == 0); assert(ioctl(pmu_fd[i], PERF_EVENT_IOC_ENABLE) == 0); } - system("dd if=/dev/zero of=/dev/null count=5000k status=none"); + + if (generate_load() < 0) { + error = 1; + goto all_cpu_err; + } print_stacks(); all_cpu_err: for (i--; i >= 0; i--) { @@ -156,7 +170,7 @@ static void test_perf_event_all_cpu(struct perf_event_attr *attr) static void test_perf_event_task(struct perf_event_attr *attr) { - int pmu_fd; + int pmu_fd, error = 0; /* per task perf event, enable inherit so the "dd ..." command can be traced properly. * Enabling inherit will cause bpf_perf_prog_read_time helper failure. @@ -171,10 +185,17 @@ static void test_perf_event_task(struct perf_event_attr *attr) } assert(ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd[0]) == 0); assert(ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE) == 0); - system("dd if=/dev/zero of=/dev/null count=5000k status=none"); + + if (generate_load() < 0) { + error = 1; + goto err; + } print_stacks(); +err: ioctl(pmu_fd, PERF_EVENT_IOC_DISABLE); close(pmu_fd); + if (error) + int_exit(0); } static void test_bpf_perf_event(void) -- 2.17.1
[PATCH v2 0/4] samples/bpf: simple fixes
v2: - in error cases, do return; instead of break; in loop Hello, This patchset fixes trivial things that I found when testing 'samples/bpf/' sample code. I'd appreciate it, if you review this. Thanks, Taeung Taeung Song (4): samples/bpf: add missing samples/bpf: Check the result of system() samples/bpf: Check the error of write() and read() samples/bpf: add .gitignore file samples/bpf/.gitignore | 49 samples/bpf/parse_varlen.c | 6 +--- samples/bpf/test_overhead_user.c | 19 ++--- samples/bpf/trace_event_user.c | 27 -- 4 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 samples/bpf/.gitignore -- 2.17.1
[PATCH v2 1/4] samples/bpf: add missing
This fixes build error regarding redefinition: CLANG-bpf samples/bpf/parse_varlen.o samples/bpf/parse_varlen.c:111:8: error: redefinition of 'vlan_hdr' struct vlan_hdr { ^ ./include/linux/if_vlan.h:38:8: note: previous definition is here So remove duplicate 'struct vlan_hdr' in sample code and include if_vlan.h Signed-off-by: Taeung Song --- samples/bpf/parse_varlen.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/samples/bpf/parse_varlen.c b/samples/bpf/parse_varlen.c index 95c16324760c..0b6f22feb2c9 100644 --- a/samples/bpf/parse_varlen.c +++ b/samples/bpf/parse_varlen.c @@ -6,6 +6,7 @@ */ #define KBUILD_MODNAME "foo" #include +#include #include #include #include @@ -108,11 +109,6 @@ static int parse_ipv6(void *data, uint64_t nh_off, void *data_end) return 0; } -struct vlan_hdr { - uint16_t h_vlan_TCI; - uint16_t h_vlan_encapsulated_proto; -}; - SEC("varlen") int handle_ingress(struct __sk_buff *skb) { -- 2.17.1
[PATCH v2 4/4] samples/bpf: add .gitignore file
For untracked executables of samples/bpf, add this. Untracked files: (use "git add ..." to include in what will be committed) samples/bpf/cpustat samples/bpf/fds_example samples/bpf/lathist samples/bpf/load_sock_ops ... Signed-off-by: Taeung Song --- samples/bpf/.gitignore | 49 ++ 1 file changed, 49 insertions(+) create mode 100644 samples/bpf/.gitignore diff --git a/samples/bpf/.gitignore b/samples/bpf/.gitignore new file mode 100644 index ..8ae4940025f8 --- /dev/null +++ b/samples/bpf/.gitignore @@ -0,0 +1,49 @@ +cpustat +fds_example +lathist +load_sock_ops +lwt_len_hist +map_perf_test +offwaketime +per_socket_stats_example +sampleip +sock_example +sockex1 +sockex2 +sockex3 +spintest +syscall_nrs.h +syscall_tp +task_fd_query +tc_l2_redirect +test_cgrp2_array_pin +test_cgrp2_attach +test_cgrp2_attach2 +test_cgrp2_sock +test_cgrp2_sock2 +test_current_task_under_cgroup +test_lru_dist +test_map_in_map +test_overhead +test_probe_write_user +trace_event +trace_output +tracex1 +tracex2 +tracex3 +tracex4 +tracex5 +tracex6 +tracex7 +xdp1 +xdp2 +xdp_adjust_tail +xdp_fwd +xdp_monitor +xdp_redirect +xdp_redirect_cpu +xdp_redirect_map +xdp_router_ipv4 +xdp_rxq_info +xdp_tx_iptunnel +xdpsock -- 2.17.1
[PATCH 2/2] perf tools: Add options 'get', 'set' and 'unset' to 'perf-config'.
Add 'get' option that can show value of a specific config variable and 'set' and 'unset' option that can create or replace a config variable. Signed-off-by: Taeung Song --- tools/perf/builtin-config.c | 198 tools/perf/util/cache.h | 18 +++- tools/perf/util/config.c| 35 +++- 3 files changed, 247 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 494bd73..b0885ff 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -15,14 +15,25 @@ static struct { bool list_action; + bool get_action; + bool set_action; + bool unset_action; } params; +LIST_HEAD(sections); +static char *section_name_; +static char *subkey_; +static char *value_; + static const char * const config_usage[] = { "perf config [options]", NULL }; static const struct option config_options[] = { OPT_BOOLEAN('l', "list", ¶ms.list_action, "list up current configurations"), + OPT_BOOLEAN(0, "get", ¶ms.get_action, "get value: section.subkey"), + OPT_BOOLEAN(0, "set", ¶ms.set_action, "create or replace a variable: section.subkey value"), + OPT_BOOLEAN(0, "unset", ¶ms.unset_action, "remove a variable: section.subkey"), OPT_END() }; @@ -34,6 +45,72 @@ static void check_argc(int argc, int min, int max) usage_with_options(config_usage, config_options); } +static struct config_section *find_config_section(const char *section_name) +{ + struct config_section *section_node; + list_for_each_entry(section_node, §ions, list) + if (!strcmp(section_node->name, section_name)) + return section_node; + + return NULL; +} + +static struct config_element *find_config_element(const char *subkey + , struct config_section *section_node) +{ + struct config_element *element_node; + + list_for_each_entry(element_node, §ion_node->element_head, list) + if (!strcmp(element_node->subkey, subkey)) + return element_node; + + return NULL; +} + +static struct config_section *init_config_section(const char *section_name) +{ + struct config_section *section_node; + LIST_HEAD(element_head); + + section_node = zalloc(sizeof(*section_node)); + if (!section_node) + return NULL; + + INIT_LIST_HEAD(§ion_node->element_head); + list_splice(&element_head, §ion_node->element_head); + section_node->name = strdup(section_name); + if (!section_node->name) { + pr_err("%s: strdup failed\n", __func__); + return NULL; + } + + return section_node; +} + +static int add_config_element(struct list_head *head + , const char *subkey, const char *value) +{ + struct config_element *element_node; + element_node = zalloc(sizeof(*element_node)); + element_node->subkey = strdup(subkey); + if (!element_node->subkey) { + pr_err("%s: strdup failed\n", __func__); + return -1; + } + if (value) { + element_node->value = strdup(value); + if (!element_node->value) { + pr_err("%s: strdup failed\n", __func__); + return -1; + } + } else + element_node->value = NULL; + + list_add_tail(&element_node->list, head); + + return 0; +} + static int show_config(const char *key, const char *value, void *cb __maybe_unused) { @@ -45,6 +122,112 @@ static int show_config(const char *key, const char *value, return 0; } +static int show_spec_config(struct config_section *section_node + , struct config_element *element_node) +{ + char key[BUFSIZ]; + + if (section_node && element_node) { + sprintf(key, "%s.%s", section_node->name, element_node->subkey); + show_config(key, element_node->value, NULL); + } + + return 0; +} + +static int set_config(struct config_section *section_node, struct config_element *element_node) +{ + if (!value_) { + /* value == NULL means unset */ + if (section_node && element_node) + element_node->value = NULL; + else /* do nothing */ + return 0; + } else { + /* if there isn't existent section, add a new section */ + if (!section_node) { + section_node = init_config_section(section_name_); +
[PATCH 1/2] perf tools: Add 'perf-config' command
The perf configuration file contain many variables which can make the perf command's action more effective and more skilful. 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 and a document for it. Signed-off-by: Taeung Song --- tools/perf/Build| 1 + tools/perf/Documentation/perf-config.txt| 418 tools/perf/Documentation/perfconfig.example | 65 - tools/perf/builtin-config.c | 67 + tools/perf/builtin.h| 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 1 + 7 files changed, 543 insertions(+), 11 deletions(-) create mode 100644 tools/perf/Documentation/perf-config.txt create mode 100644 tools/perf/builtin-config.c diff --git a/tools/perf/Build b/tools/perf/Build index b77370e..3c1f437 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/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt new file mode 100644 index 000..62f6bcb --- /dev/null +++ b/tools/perf/Documentation/perf-config.txt @@ -0,0 +1,418 @@ +perf-config(1) +== + +NAME + +perf-config - Get and set variables in configuration file. + +SYNOPSIS + +[verse] +'perf config' --list + +DESCRIPTION +--- +You can manage variables in configuration file with this command. + +OPTIONS +--- + +-l:: +--list:: + Show all variables with key and value into each sections. + +CONFIGURATION FILE +-- + +The Perf configuration file contain many variables which can make +the perf command's action more effective, more skilful. +The '$HOME/.perfconfig' file is used to store a per-user configuration. +The file 'etc/perfconfig' or '$(sysconfdir)/perfconfig' can be used to +store a system-wide default configuration. + +The variables are divided into sections. In each sections, the variables +can contain a key and values. + +Syntax +~~ + +Example +~~~ + +Given a $HOME/.perfconfig like this: + +# +# This is the config file, and +# a '#' and ';' character indicates a comment +# + +[colors] + # Color variables + top = red, default + medium = green, default + normal = lightgray, default + selected = white, lightgray + code = blue, default + addr = magenta, default + root = white, blue + +[tui] + # Defaults if linked with libslang + report = on + annotate = on + top = on + +[buildid] + # Default, disable using /dev/null + dir = /root/.debug + +[annotate] + # Defaults + hide_src_code = false + use_offset = true + jump_arrows = true + show_nr_jumps = false + +[help] + # Format can be man, info, web or html + format = man + autocorrect = 0 + +[ui] + show-headers= true + +[call-graph] + # fp (framepointer), dwarf + record-mode = fp + print-type = graph + order = caller + sort-key = function + +Variables +~ + +colors.*:: + Color variables can appoint colors of the output which is printed out + from ‘report’, ‘top’,’annotate’ on tui. + Color variables is composed of foreground and background + and should have two values for them. If you want to set as colors + of your terminal, you should use ‘default’ for color value. +The kind of color which can be used as below. + red, green, default, black, blue, white, magenta, lightgray + + colors.top:: + ‘top’ means a overhead percentage which has more than 5%. + And values of it’s variable specify colors of percentage. + Basic key values are foreground-color ’red’ and + background-color ’default’. + colors.medium:: + ‘medium’ means a overhead percentage which has more than 0.5%. + Default values are ’green’ and ’default’. + colors.normal:: + ‘normal’ means rest of overhead percentages + except ‘top’, ‘medium’, ‘selected’. + Default values are ’lightgray’ and ’default’. + colors.selected:: + This appoint colors for forcussed one of the output list + from sub-commands (top,report,annotate). + Default values are ’white’ and ’lightgray’. + colors.code:: + Colors for a arrow and lines on jumping by assembly code + such as ‘jns’,’jmp’,’jane’,etc. Default values are ‘blue’, ‘defau
[PATCH 4/4] perf tools: Add a option 'remove' to perf-config.
A option 'remove' is to remove specific config variables. For the syntax examples, # perf config -r | --remove [section.subkey ...] Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 6 tools/perf/builtin-config.c | 48 +++- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 1c9027e..fb8ca74 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -13,6 +13,8 @@ or 'perf config' -l | --list or 'perf config' -a | --all +or +'perf config' -r | --remove [section.subkey ...] DESCRIPTION --- @@ -29,6 +31,10 @@ OPTIONS --all:: Show current and all possible config variables with default values. +-r:: +--remove:: + Remove specific config variables. + CONFIGURATION FILE -- diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index a67aea3..ff49c22 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -18,6 +18,7 @@ static struct { bool get_action; bool set_action; bool all_action; + bool remove_action; } params; struct list_head *sections; @@ -31,6 +32,7 @@ static const struct option config_options[] = { OPT_BOOLEAN('l', "list", ¶ms.list_action, "show current config variables"), OPT_BOOLEAN('a', "all", ¶ms.all_action, "show current and all possible config variables with default values"), + OPT_BOOLEAN('r', "remove", ¶ms.remove_action, "remove specific variables: [section.subkey ...]"), OPT_END() }; @@ -150,19 +152,26 @@ static int set_config(const char *section_name, const char *subkey, find_config(§ion_node, &element_node, section_name, subkey); - /* if there isn't existent section, add a new section */ - if (!section_node) { - section_node = init_config_section(section_name); - if (!section_node) - return -1; - list_add_tail(§ion_node->list, sections); + if (!value) { + /* value == NULL means remove the variable */ + if (section_node && element_node) + element_node->value = NULL; + else + pr_err("Error: Failed to find the variable.\n"); + } else { + /* if there isn't existent section, add a new section */ + if (!section_node) { + section_node = init_config_section(section_name); + if (!section_node) + return -1; + list_add_tail(§ion_node->list, sections); + } + /* if nothing to replace, add a new element which contains key-value pair. */ + if (!element_node) + return add_config_element(§ion_node->element_head, subkey, value); + else + element_node->value = (char *)value;; } - /* if nothing to replace, add a new element which contains key-value pair. */ - if (!element_node) - return add_config_element(§ion_node->element_head, subkey, value); - else - element_node->value = (char *)value; - return 0; } @@ -367,7 +376,20 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) ret = perf_config(show_config, NULL); else if (params.all_action && argc == 0) ret = show_all_config(); - else { + else if (params.remove_action) { + for (i = 0; argv[i]; i++) { + value = strrchr(argv[i], '='); + if (value == NULL || value == argv[0]) + ret = perf_configset_with_option(set_spec_config, argv[i]); + else { + pr_err("invalid key: %s", argv[i]); + return -1; + } + if (ret < 0) + goto out; + } + } else { + pr_warning("Error: Unknown argument.\n"); usage_with_options(config_usage, config_options); } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/4] perf tools: Add 'perf-config' command
The perf configuration file contains many variables which can make the perf command's action more effective and more skilful. 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 and a document for it. Signed-off-by: Taeung Song --- tools/perf/Build| 1 + tools/perf/Documentation/perf-config.txt| 436 tools/perf/Documentation/perfconfig.example | 68 - tools/perf/builtin-config.c | 56 tools/perf/builtin.h| 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 1 + 7 files changed, 553 insertions(+), 11 deletions(-) create mode 100644 tools/perf/Documentation/perf-config.txt create mode 100644 tools/perf/builtin-config.c diff --git a/tools/perf/Build b/tools/perf/Build index b77370e..3c1f437 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/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt new file mode 100644 index 000..489c2c6 --- /dev/null +++ b/tools/perf/Documentation/perf-config.txt @@ -0,0 +1,436 @@ +perf-config(1) +== + +NAME + +perf-config - Get and set variables in configuration file. + +SYNOPSIS + +[verse] +'perf config' -l | --list + +DESCRIPTION +--- +You can manage variables in configuration file with this command. + +OPTIONS +--- + +-l:: +--list:: + Show current config variables with key and value into each sections. + +CONFIGURATION FILE +-- + +The Perf configuration file contain many variables which can make +the perf command's action more effective, more skilful. +The '$HOME/.perfconfig' file is used to store a per-user configuration. +The file 'etc/perfconfig' or '$(sysconfdir)/perfconfig' can be used to +store a system-wide default configuration. + +The variables are divided into sections. In each sections, the variables +can contain a key and values. + +Syntax +~~ + +The file consists of sections and subkeys. A section begins with +the name of the section in square brackets and continues until the next +section begins. Each variable have to belong to some section, which means +there must be a section header before the first setting of a variable, as below: +Each variable are in the form 'subkey = value'. + + [section] + subkey1 = value1 + subkey2 = value2 + +Subsection names are case sensitive and can contain any characters except +newline (doublequote `"` and backslash have to be escaped as `\"` and `\\`, +respectively). Section headers cannot span multiple +lines. Variables may belong directly to a section or to a given subsection. + +Example +~~~ + +Given a $HOME/.perfconfig like this: + +# +# This is the config file, and +# a '#' and ';' character indicates a comment +# + +[colors] + # Color variables + top = red, default + medium = green, default + normal = lightgray, default + selected = white, lightgray + code = blue, default + addr = magenta, default + root = white, blue + +[tui] + # Defaults if linked with libslang + report = on + annotate = on + top = on + +[buildid] + # Default, disable using /dev/null + dir = /root/.debug + +[annotate] + # Defaults + hide_src_code = false + use_offset = true + jump_arrows = true + show_nr_jumps = false + +[help] + # Format can be man, info, web or html + format = man + autocorrect = 0 + +[ui] + show-headers= true + +[call-graph] + # fp (framepointer), dwarf + record-mode = fp + print-type = graph + order = caller + sort-key = function + +Variables +~ + +colors.*:: + Color variables can appoint colors of the output which is printed out + from ‘report’, ‘top’,’annotate’ on tui. + Color variables is composed of foreground and background + and should have two values for them. If you want to set as colors + of your terminal, you should use ‘default’ for color value. +The kind of color which can be used as below. + red, green, default, black, blue, white, magenta, lightgray + + colors.top:: + ‘top’ means a overhead percentage which has more than 5%. + And values of it’s variable specify colors of percentage. + Basic key values are foreground-color ’red’ and + background-co
[PATCH 2/4] perf tools: Add functions which can get or set perf config variables.
This patch consists of functions which can get, set specific config variables. For the syntax examples, perf config [options] [section.subkey[=value] ...] display key-value pairs of specific config variables # perf config report.queue-size report.children set specific config variables # perf config report.queue-size=100M report.children=true Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 2 + tools/perf/builtin-config.c | 276 ++- tools/perf/util/cache.h | 17 ++ tools/perf/util/config.c | 30 +++- 4 files changed, 320 insertions(+), 5 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 489c2c6..b2b3321 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 configuration file. SYNOPSIS [verse] +'perf config' [section.subkey[=value] ...] +or 'perf config' -l | --list DESCRIPTION diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 9e4ba72..99292f6 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -15,10 +15,14 @@ static struct { bool list_action; + bool get_action; + bool set_action; } params; +struct list_head *sections; + static const char * const config_usage[] = { - "perf config [options]", + "perf config [options] [section.subkey[=value] ...]", NULL }; static const struct option config_options[] = { @@ -27,6 +31,74 @@ static const struct option config_options[] = { OPT_END() }; +static struct config_section *find_config_section(const char *section_name) +{ + struct config_section *section_node; + list_for_each_entry(section_node, sections, list) + if (!strcmp(section_node->name, section_name)) + return section_node; + + return NULL; +} + +static struct config_element *find_config_element(const char *subkey, + struct config_section *section_node) +{ + struct config_element *element_node; + + list_for_each_entry(element_node, §ion_node->element_head, list) + if (!strcmp(element_node->subkey, subkey)) + return element_node; + + return NULL; +} + +static struct config_section *init_config_section(const char *section_name) +{ + struct config_section *section_node; + + section_node = zalloc(sizeof(*section_node)); + if (!section_node) + return NULL; + + INIT_LIST_HEAD(§ion_node->element_head); + section_node->name = strdup(section_name); + if (!section_node->name) { + pr_err("%s: strdup failed\n", __func__); + free(section_node); + return NULL; + } + + return section_node; +} + +static int add_config_element(struct list_head *head, + const char *subkey, const char *value) +{ + struct config_element *element_node; + element_node = zalloc(sizeof(*element_node)); + element_node->subkey = strdup(subkey); + if (!element_node->subkey) { + pr_err("%s: strdup failed\n", __func__); + goto out_free; + } + if (value) { + element_node->value = strdup(value); + if (!element_node->value) { + pr_err("%s: strdup failed\n", __func__); + goto out_free; + } + } else + element_node->value = NULL; + + list_add_tail(&element_node->list, head); + return 0; + +out_free: + free(element_node); + return -1; +} + static int show_config(const char *key, const char *value, void *cb __maybe_unused) { @@ -38,12 +110,211 @@ static int show_config(const char *key, const char *value, return 0; } -int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) +static void find_config(struct config_section **section_node, struct config_element **element_node, + const char *given_section_name, const char *given_subkey) +{ + *section_node = find_config_section(given_section_name); + + if (*section_node != NULL) + *element_node = find_config_element(given_subkey, *section_node); + else + *element_node = NULL; +} + +static int show_spec_config(const char *section_name, const char *subkey, + const char *value __maybe_unused) +{ + struct config_section *section_node = NULL; + struct config_element *element_node = NULL; + char key[BUFSIZ]; + + find_config(§ion_node, &element_no
[PATCH 3/4] perf tools: Add a option 'all' to perf-config.
A option 'all' is to display both current config variables and all possible config variables with default values. The syntax examples are like below perf config [options] display all perf config with default values. # perf config or # perf config -a | --all Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 6 +++ tools/perf/builtin-config.c | 49 tools/perf/util/PERFCONFIG-DEFAULT | 65 tools/perf/util/cache.h | 1 + tools/perf/util/config.c | 2 +- 5 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 tools/perf/util/PERFCONFIG-DEFAULT diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index b2b3321..1c9027e 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -11,6 +11,8 @@ SYNOPSIS 'perf config' [section.subkey[=value] ...] or 'perf config' -l | --list +or +'perf config' -a | --all DESCRIPTION --- @@ -23,6 +25,10 @@ OPTIONS --list:: Show current config variables with key and value into each sections. +-a:: +--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 99292f6..a67aea3 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -17,6 +17,7 @@ static struct { bool list_action; bool get_action; bool set_action; + bool all_action; } params; struct list_head *sections; @@ -28,6 +29,8 @@ static const char * const config_usage[] = { static const struct option config_options[] = { OPT_GROUP("Action"), OPT_BOOLEAN('l', "list", ¶ms.list_action, "show current config variables"), + OPT_BOOLEAN('a', "all", ¶ms.all_action, + "show current and all possible config variables with default values"), OPT_END() }; @@ -204,6 +207,49 @@ static int collect_config(const char *var, const char *value, return add_config_element(§ion_node->element_head, subkey, value); } +static int merge_config(const char *var, const char *value, + void *cb __maybe_unused) +{ + const char *section_name, *subkey; + parse_key(var, §ion_name, &subkey); + return set_config(section_name, subkey, value); +} + +static int show_all_config(void) +{ + int ret = 0; + struct config_section *section_node; + struct config_element *element_node; + char *pwd, *all_config; + + pwd = getenv("PWD"); + all_config = strdup(mkpath("%s/util/PERFCONFIG-DEFAULT", pwd)); + + if (!all_config) { + pr_err("%s: strdup failed\n", __func__); + return -1; + } + + sections = zalloc(sizeof(*sections)); + if (!sections) + return -1; + INIT_LIST_HEAD(sections); + + ret += perf_config_from_file(collect_config, all_config, NULL); + ret += perf_config(merge_config, NULL); + + list_for_each_entry(section_node, sections, list) { + list_for_each_entry(element_node, §ion_node->element_head, list) { + if (element_node->value) + printf("%s.%s = %s\n", section_node->name, + element_node->subkey, element_node->value); + else + printf("%s.%s =\n", section_node->name, element_node->subkey); + } + } + return ret; +} + static int perf_configset_with_option(configset_fn_t fn, const char *var) { int i, num_dot = 0, num_equals = 0; @@ -301,6 +347,7 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) if (!is_option && argc >= 0) { switch (argc) { case 0: + params.all_action = true; break; default: for (i = 0; argv[i]; i++) { @@ -318,6 +365,8 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) if (params.list_action && argc == 0) ret = perf_config(show_config, NULL); + else if (params.all_action && argc == 0) + ret = show_all_config(); else { pr_warning("Error: Unknown argument.\n"); usage_with_options(config_usage, config_options); diff --git a/tools/perf/util/PERFCONFIG-DEFAULT b/tools/perf/util/PERFCONFIG-DEFAULT new file mode 100644 index 000..ddb67db --- /dev/null +++ b/tools/per
[PATCH 2/2] perf tools: Add a option 'remove' to perf-config and features which get or set a config variable.
This patch consists of adding functions which get, set or remove a specific config variable. For the syntax examples, perf config [options] [section.subkey[=value]] display all perf config with default values # perf config or # perf config -a | --all display a specific key(section.subkey) and value # perf config report.queue set a specific key and value # perf config report.queue=100M remove a specific key # perf config -r | --remove report.queue Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 8 ++ tools/perf/builtin-config.c | 223 ++- tools/perf/util/cache.h | 17 +++ tools/perf/util/config.c | 35 - 4 files changed, 277 insertions(+), 6 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index b251702..7354b18 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -8,7 +8,11 @@ perf-config - Get and set variables in configuration file. SYNOPSIS [verse] +'perf config' section.subkey[=value] +or 'perf config' -a | --all +or +'perf config' -r | --remove section.subkey DESCRIPTION --- @@ -21,6 +25,10 @@ OPTIONS --all:: Show all variables with key and value into each sections. +-r:: +--remove:: + Remove a specific variable. + CONFIGURATION FILE -- diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 32f8ae6..20ae4a2 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -15,15 +15,24 @@ static struct { bool all_action; + bool get_action; + bool set_action; + bool remove_action; } params; +LIST_HEAD(sections); +static char *given_section_name; +static char *given_subkey; +static char *given_value; + static const char * const config_usage[] = { - "perf config [options]", + "perf config [options] [section.subkey[=value]]", NULL }; static const struct option config_options[] = { OPT_GROUP("Action"), OPT_BOOLEAN('a', "all", ¶ms.all_action, "print all configurations"), + OPT_BOOLEAN('r', "remove", ¶ms.remove_action, "remove a variable: section.subkey"), OPT_END() }; @@ -35,6 +44,72 @@ static void check_argc(int argc, int limit) usage_with_options(config_usage, config_options); } +static struct config_section *find_config_section(const char *section_name) +{ + struct config_section *section_node; + list_for_each_entry(section_node, §ions, list) + if (!strcmp(section_node->name, section_name)) + return section_node; + + return NULL; +} + +static struct config_element *find_config_element(const char *subkey + , struct config_section *section_node) +{ + struct config_element *element_node; + + list_for_each_entry(element_node, §ion_node->element_head, list) + if (!strcmp(element_node->subkey, subkey)) + return element_node; + + return NULL; +} + +static struct config_section *init_config_section(const char *section_name) +{ + struct config_section *section_node; + LIST_HEAD(element_head); + + section_node = zalloc(sizeof(*section_node)); + if (!section_node) + return NULL; + + INIT_LIST_HEAD(§ion_node->element_head); + list_splice(&element_head, §ion_node->element_head); + section_node->name = strdup(section_name); + if (!section_node->name) { + pr_err("%s: strdup failed\n", __func__); + return NULL; + } + + return section_node; +} + +static int add_config_element(struct list_head *head + , const char *subkey, const char *value) +{ + struct config_element *element_node; + element_node = zalloc(sizeof(*element_node)); + element_node->subkey = strdup(subkey); + if (!element_node->subkey) { + pr_err("%s: strdup failed\n", __func__); + return -1; + } + if (value) { + element_node->value = strdup(value); + if (!element_node->value) { + pr_err("%s: strdup failed\n", __func__); + return -1; + } + } else + element_node->value = NULL; + + list_add_tail(&element_node->list, head); + + return 0; +} + static int show_config(const char *key, const char *value, void *cb __maybe_unused) { @@ -46,22 +121,164 @@ static int show_config(const char *key, const char *value,
[PATCH 1/2] perf tools: Add 'perf-config' command
The perf configuration file contain many variables which can make the perf command's action more effective and more skilful. 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 '--all' option and a document for it. Signed-off-by: Taeung Song --- tools/perf/Build| 1 + tools/perf/Documentation/perf-config.txt| 433 tools/perf/Documentation/perfconfig.example | 65 - tools/perf/builtin-config.c | 68 + tools/perf/builtin.h| 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 1 + 7 files changed, 559 insertions(+), 11 deletions(-) create mode 100644 tools/perf/Documentation/perf-config.txt create mode 100644 tools/perf/builtin-config.c diff --git a/tools/perf/Build b/tools/perf/Build index b77370e..3c1f437 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/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt new file mode 100644 index 000..b251702 --- /dev/null +++ b/tools/perf/Documentation/perf-config.txt @@ -0,0 +1,433 @@ +perf-config(1) +== + +NAME + +perf-config - Get and set variables in configuration file. + +SYNOPSIS + +[verse] +'perf config' -a | --all + +DESCRIPTION +--- +You can manage variables in configuration file with this command. + +OPTIONS +--- + +-a:: +--all:: + Show all variables with key and value into each sections. + +CONFIGURATION FILE +-- + +The Perf configuration file contain many variables which can make +the perf command's action more effective, more skilful. +The '$HOME/.perfconfig' file is used to store a per-user configuration. +The file 'etc/perfconfig' or '$(sysconfdir)/perfconfig' can be used to +store a system-wide default configuration. + +The variables are divided into sections. In each sections, the variables +can contain a key and values. + +Syntax +~~ + +The file consists of sections and subkeys. A section begins with +the name of the section in square brackets and continues until the next +section begins. Each variable have to belong to some section, which means +there must be a section header before the first setting of a variable, as below: +Each variable are in the form 'subkey = value'. + + [section] + subkey1 = value1 + subkey2 = value2 + +Subsection names are case sensitive and can contain any characters except +newline (doublequote `"` and backslash have to be escaped as `\"` and `\\`, +respectively). Section headers cannot span multiple +lines. Variables may belong directly to a section or to a given subsection. + +Example +~~~ + +Given a $HOME/.perfconfig like this: + +# +# This is the config file, and +# a '#' and ';' character indicates a comment +# + +[colors] + # Color variables + top = red, default + medium = green, default + normal = lightgray, default + selected = white, lightgray + code = blue, default + addr = magenta, default + root = white, blue + +[tui] + # Defaults if linked with libslang + report = on + annotate = on + top = on + +[buildid] + # Default, disable using /dev/null + dir = /root/.debug + +[annotate] + # Defaults + hide_src_code = false + use_offset = true + jump_arrows = true + show_nr_jumps = false + +[help] + # Format can be man, info, web or html + format = man + autocorrect = 0 + +[ui] + show-headers= true + +[call-graph] + # fp (framepointer), dwarf + record-mode = fp + print-type = graph + order = caller + sort-key = function + +Variables +~ + +colors.*:: + Color variables can appoint colors of the output which is printed out + from ‘report’, ‘top’,’annotate’ on tui. + Color variables is composed of foreground and background + and should have two values for them. If you want to set as colors + of your terminal, you should use ‘default’ for color value. +The kind of color which can be used as below. + red, green, default, black, blue, white, magenta, lightgray + + colors.top:: + ‘top’ means a overhead percentage which has more than 5%. + And values of it’s variable specify colors of percentage. + Basic key values are foreground-color ’red’ and + background-color ’default’. + colors.med
[PATCH 1/2] perf tools: Add 'perf-config' command
The perf configuration file contains many variables which can make the perf command's action more effective and more skilful. 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 '--all' option and a document for it. Signed-off-by: Taeung Song --- tools/perf/Build| 1 + tools/perf/Documentation/perf-config.txt| 433 tools/perf/Documentation/perfconfig.example | 65 - tools/perf/builtin-config.c | 71 + tools/perf/builtin.h| 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 1 + 7 files changed, 562 insertions(+), 11 deletions(-) create mode 100644 tools/perf/Documentation/perf-config.txt create mode 100644 tools/perf/builtin-config.c diff --git a/tools/perf/Build b/tools/perf/Build index b77370e..3c1f437 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/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt new file mode 100644 index 000..b251702 --- /dev/null +++ b/tools/perf/Documentation/perf-config.txt @@ -0,0 +1,433 @@ +perf-config(1) +== + +NAME + +perf-config - Get and set variables in configuration file. + +SYNOPSIS + +[verse] +'perf config' -a | --all + +DESCRIPTION +--- +You can manage variables in configuration file with this command. + +OPTIONS +--- + +-a:: +--all:: + Show all variables with key and value into each sections. + +CONFIGURATION FILE +-- + +The Perf configuration file contain many variables which can make +the perf command's action more effective, more skilful. +The '$HOME/.perfconfig' file is used to store a per-user configuration. +The file 'etc/perfconfig' or '$(sysconfdir)/perfconfig' can be used to +store a system-wide default configuration. + +The variables are divided into sections. In each sections, the variables +can contain a key and values. + +Syntax +~~ + +The file consists of sections and subkeys. A section begins with +the name of the section in square brackets and continues until the next +section begins. Each variable have to belong to some section, which means +there must be a section header before the first setting of a variable, as below: +Each variable are in the form 'subkey = value'. + + [section] + subkey1 = value1 + subkey2 = value2 + +Subsection names are case sensitive and can contain any characters except +newline (doublequote `"` and backslash have to be escaped as `\"` and `\\`, +respectively). Section headers cannot span multiple +lines. Variables may belong directly to a section or to a given subsection. + +Example +~~~ + +Given a $HOME/.perfconfig like this: + +# +# This is the config file, and +# a '#' and ';' character indicates a comment +# + +[colors] + # Color variables + top = red, default + medium = green, default + normal = lightgray, default + selected = white, lightgray + code = blue, default + addr = magenta, default + root = white, blue + +[tui] + # Defaults if linked with libslang + report = on + annotate = on + top = on + +[buildid] + # Default, disable using /dev/null + dir = /root/.debug + +[annotate] + # Defaults + hide_src_code = false + use_offset = true + jump_arrows = true + show_nr_jumps = false + +[help] + # Format can be man, info, web or html + format = man + autocorrect = 0 + +[ui] + show-headers= true + +[call-graph] + # fp (framepointer), dwarf + record-mode = fp + print-type = graph + order = caller + sort-key = function + +Variables +~ + +colors.*:: + Color variables can appoint colors of the output which is printed out + from ‘report’, ‘top’,’annotate’ on tui. + Color variables is composed of foreground and background + and should have two values for them. If you want to set as colors + of your terminal, you should use ‘default’ for color value. +The kind of color which can be used as below. + red, green, default, black, blue, white, magenta, lightgray + + colors.top:: + ‘top’ means a overhead percentage which has more than 5%. + And values of it’s variable specify colors of percentage. + Basic key values are foreground-color ’red’ and + background-color ’default’. + col
[PATCH 2/2] perf tools: Add a option 'remove' to perf-config and features which get or set a config variable.
This patch consists of adding functions which get, set or remove a specific config variable. For the syntax examples, perf config [options] [section.subkey[=value]] display a specific key(section.subkey) and value # perf config report.queue set a specific key and value # perf config report.queue=100M remove a specific key # perf config -r | --remove report.queue Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 8 ++ tools/perf/builtin-config.c | 224 ++- tools/perf/util/cache.h | 17 +++ tools/perf/util/config.c | 35 - 4 files changed, 278 insertions(+), 6 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index b251702..7354b18 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -8,7 +8,11 @@ perf-config - Get and set variables in configuration file. SYNOPSIS [verse] +'perf config' section.subkey[=value] +or 'perf config' -a | --all +or +'perf config' -r | --remove section.subkey DESCRIPTION --- @@ -21,6 +25,10 @@ OPTIONS --all:: Show all variables with key and value into each sections. +-r:: +--remove:: + Remove a specific variable. + CONFIGURATION FILE -- diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 7cf6d03..205e053 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -15,15 +15,24 @@ static struct { bool all_action; + bool get_action; + bool set_action; + bool remove_action; } params; +LIST_HEAD(sections); +static char *given_section_name; +static char *given_subkey; +static char *given_value; + static const char * const config_usage[] = { - "perf config [options]", + "perf config [options] [section.subkey[=value]]", NULL }; static const struct option config_options[] = { OPT_GROUP("Action"), OPT_BOOLEAN('a', "all", ¶ms.all_action, "print all configurations"), + OPT_BOOLEAN('r', "remove", ¶ms.remove_action, "remove a variable: section.subkey"), OPT_END() }; @@ -35,6 +44,72 @@ static void check_argc(int argc, int limit) usage_with_options(config_usage, config_options); } +static struct config_section *find_config_section(const char *section_name) +{ + struct config_section *section_node; + list_for_each_entry(section_node, §ions, list) + if (!strcmp(section_node->name, section_name)) + return section_node; + + return NULL; +} + +static struct config_element *find_config_element(const char *subkey + , struct config_section *section_node) +{ + struct config_element *element_node; + + list_for_each_entry(element_node, §ion_node->element_head, list) + if (!strcmp(element_node->subkey, subkey)) + return element_node; + + return NULL; +} + +static struct config_section *init_config_section(const char *section_name) +{ + struct config_section *section_node; + LIST_HEAD(element_head); + + section_node = zalloc(sizeof(*section_node)); + if (!section_node) + return NULL; + + INIT_LIST_HEAD(§ion_node->element_head); + list_splice(&element_head, §ion_node->element_head); + section_node->name = strdup(section_name); + if (!section_node->name) { + pr_err("%s: strdup failed\n", __func__); + return NULL; + } + + return section_node; +} + +static int add_config_element(struct list_head *head + , const char *subkey, const char *value) +{ + struct config_element *element_node; + element_node = zalloc(sizeof(*element_node)); + element_node->subkey = strdup(subkey); + if (!element_node->subkey) { + pr_err("%s: strdup failed\n", __func__); + return -1; + } + if (value) { + element_node->value = strdup(value); + if (!element_node->value) { + pr_err("%s: strdup failed\n", __func__); + return -1; + } + } else + element_node->value = NULL; + + list_add_tail(&element_node->list, head); + + return 0; +} + static int show_config(const char *key, const char *value, void *cb __maybe_unused) { @@ -46,22 +121,165 @@ static int show_config(const char *key, const char *value, return 0; } +static int show_spec_config(struct config_section *section_node +
[PATCH v2 1/4] perf tools: Add 'perf-config' command
The perf configuration file contains many variables which can make the perf command's action more effective. 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 and a document for it. perf config [options] display current perf config variables. # perf config or # perf config -l | --list Signed-off-by: Taeung Song --- tools/perf/Build| 1 + tools/perf/Documentation/perf-config.txt| 375 tools/perf/Documentation/perfconfig.example | 70 +- tools/perf/builtin-config.c | 75 ++ tools/perf/builtin.h| 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 1 + 7 files changed, 512 insertions(+), 12 deletions(-) create mode 100644 tools/perf/Documentation/perf-config.txt create mode 100644 tools/perf/builtin-config.c diff --git a/tools/perf/Build b/tools/perf/Build index b77370e..3c1f437 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/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt new file mode 100644 index 000..afda861 --- /dev/null +++ b/tools/perf/Documentation/perf-config.txt @@ -0,0 +1,375 @@ +perf-config(1) +== + +NAME + +perf-config - Get and set variables in a configuration file. + +SYNOPSIS + +[verse] +'perf config' -l | --list + +DESCRIPTION +--- +You can manage variables in a configuration file with this command. + +OPTIONS +--- + +-l:: +--list:: + Show current config variables with key and value into each sections. + +CONFIGURATION FILE +-- + +The Perf configuration file contains many variables which can make +the perf command's action more effective. +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. + +The variables are divided into sections. In each section, the variables +can are composed of a key and value. + +Syntax +~~ + +The file consists of sections and names. A section begins with +the name of the section in square brackets and continues until the next +section begins. Each variable have to belong to some section, which means +there must be a section header before the first setting of a variable, as below: +Each variable are in the form 'name = value'. + + [section] + name1 = value1 + name2 = value2 + +Section names are case sensitive and can contain any characters except +newline (doublequote `"` and backslash have to be escaped as `\"` and `\\`, +respectively). Section headers can't span multiple +lines. Variables may belong directly to a section. + +Example +~~~ + +Given a $HOME/.perfconfig like this: + +# +# This is the config file, and +# a '#' and ';' character indicates a comment +# + +[colors] + # Color variables + top = red, default + medium = green, default + normal = lightgray, default + selected = white, lightgray + code = blue, default + addr = magenta, default + root = white, blue + +[tui] + # Defaults if linked with libslang + report = on + annotate = on + top = on + +[buildid] + # Default, disable using /dev/null + dir = ~/.debug + +[annotate] + # Defaults + hide_src_code = false + use_offset = true + jump_arrows = true + show_nr_jumps = false + +[help] + # Format can be man, info, web or html + format = man + autocorrect = 0 + +[ui] + show-headers= true + +[call-graph] + # fp (framepointer), dwarf + record-mode = fp + print-type = graph + order = caller + sort-key = function + +Variables +~ + +colors.*:: + Color variables can customize colors of the output which is printed out + from ‘report’, ‘top’, ’annotate’ on tui. + Color variables are composed of foreground and background + and should have two values for them. If you want to keep as colors + of your terminal, you should use ‘default’ for the color value. + The color names that can be used are: + red, green, default, black, blue, white, magenta, lightgray + + colors.top:: + ‘top’ means a overhead percentage which is more than 5%. + And values of this variable specify colors of percentage. + Basic key values are foreground-color ’red’ and
[PATCH v2 2/4] perf tools: Add functions which can get or set perf config variables.
This patch consists of functions which can get, set specific config variables. For the syntax examples, perf config [options] [section.name[=value] ...] display key-value pairs of specific config variables # perf config report.queue-size report.children set specific config variables # perf config report.queue-size=100M report.children=true Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 2 + tools/perf/builtin-config.c | 543 ++- tools/perf/util/cache.h | 17 + tools/perf/util/config.c | 30 +- 4 files changed, 587 insertions(+), 5 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index afda861..f3dae23 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' [section.name[=value] ...] +or 'perf config' -l | --list DESCRIPTION diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index e7784ed..175b125 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -16,7 +16,7 @@ static int actions; static const char * const config_usage[] = { - "perf config [options]", + "perf config [options] [section.name[=value] ...]", NULL }; @@ -28,6 +28,346 @@ static const struct option config_options[] = { OPT_END() }; +/* section names */ +#define COLORS "colors" +#define TUI "tui" +#define BUILDID "buildid" +#define ANNOTATE "annotate" +#define GTK "gtk" +#define PAGER "pager" +#define HELP "help" +#define HIST "hist" +#define UI "ui" +#define CALL_GRAPH "call-graph" +#define REPORT "report" +#define TOP "top" +#define MAN "man" + +/* config variable types */ +#define TYPE_INT "int" +#define TYPE_LONG "long" +#define TYPE_DIRNAME "dirname" +#define TYPE_BOOL "bool" +#define TYPE_ON_OFF "on_off" + +static struct default_configset { + const char *section_name; + const char *name, *value, *type; + +} default_configsets[] = { + { + .section_name = COLORS, + .name = "top", + .value = "red, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "medium", + .value = "green, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "normal", + .value = "lightgray, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "selected", + .value = "white, lightgray", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "code", + .value = "blue, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "addr", + .value = "magenta, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "root", + .value = "white, blue", + .type = NULL, + }, + { + .section_name = TUI, + .name = "report", + .value = "on", + .type = TYPE_ON_OFF, + }, + { + .section_name = TUI, + .name = "annotate", + .value = "on", + .type = TYPE_ON_OFF, + }, + { + .section_name = TUI, + .name = "top", + .value = "on", + .type = TYPE_ON_OFF, + }, + { + .section_name = BUILDID, + .name = "dir", + .value = "~/.debug", + .type = TYPE_DIRNAME, + }, + { + .section_name = ANNOTATE, + .name = "hide_src_code", + .value = "false", + .type = TYPE_BOOL, + }, + { + .section_name = ANNOTATE, + .name = "use_offset", + .value = "true", + .type = TYPE_BOOL, + }, + { + .section_name = ANNOTATE, + .name = "jump_arrows", + .value = "true", + .type = TYPE_B
[PATCH v2 4/4] perf tools: Add a option 'remove' to perf-config.
A option 'remove' is to remove specific config variables. For the syntax examples, # perf config -r | --remove [section.name ...] Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 6 ++ tools/perf/builtin-config.c | 25 - 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index e33e481..a543e1b 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -13,6 +13,8 @@ or 'perf config' -l | --list or 'perf config' -a | --list-all +or +'perf config' -r | --remove [section.name ...] DESCRIPTION --- @@ -29,6 +31,10 @@ OPTIONS --list-all:: Show current and all possible config variables with default values. +-r:: +--remove:: + Remove specific config variables. + CONFIGURATION FILE -- diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index cf7d61d..b7afe6e 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -22,12 +22,14 @@ static const char * const config_usage[] = { #define ACTION_LIST (1<<0) #define ACTION_LIST_ALL (1<<1) +#define ACTION_REMOVE (1<<2) static const struct option config_options[] = { OPT_GROUP("Action"), OPT_BIT('l', "list", &actions, "show current config variables", ACTION_LIST), OPT_BIT('a', "list-all", &actions, "show current and all possible config variables with default values", ACTION_LIST_ALL), + OPT_BIT('r', "remove", &actions, "remove specific variables: [section.name ...]", ACTION_REMOVE), OPT_END() }; @@ -471,7 +473,15 @@ static int set_config(const char *section_name, const char *name, char *value) struct config_element *element_node = NULL; find_config(§ion_node, &element_node, section_name, name); - if (value != NULL) { + if (!value) { + /* value == NULL means remove the variable */ + if (section_node && element_node) { + if (!element_node->value) + free(element_node->value); + element_node->value = NULL; + } else + pr_err("Error: Failed to find the variable.\n"); + } else { value = normalize_value(section_name, name, value); /* if there isn't existent section, add a new section */ @@ -490,6 +500,7 @@ static int set_config(const char *section_name, const char *name, char *value) element_node->value = value; } } + return perf_configset_write_in_full(); } @@ -633,6 +644,18 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) else goto out_err; goto out; + case ACTION_REMOVE: + for (i = 0; argv[i]; i++) { + if (value == NULL) + ret = perf_configset_with_option(set_config, argv[i], NULL); + else { + pr_err("invalid key: %s\n", argv[i]); + return -1; + } + if (ret < 0) + goto out; + } + goto out; default: if (!has_option && argc == 0) { ret = perf_config(show_config, NULL); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 3/4] perf tools: Add a option 'list-all' to perf-config.
A option 'list-all' is to display both current config variables and all possible config variables with default values. The syntax examples are like below perf config [options] display all perf config with default values. # perf config -a | --list-all Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 6 tools/perf/builtin-config.c | 48 2 files changed, 54 insertions(+) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index f3dae23..e33e481 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -11,6 +11,8 @@ SYNOPSIS 'perf config' [section.name[=value] ...] or 'perf config' -l | --list +or +'perf config' -a | --list-all DESCRIPTION --- @@ -23,6 +25,10 @@ OPTIONS --list:: Show current config variables with key and value into each sections. +-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 175b125..cf7d61d 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -21,10 +21,13 @@ static const char * const config_usage[] = { }; #define ACTION_LIST (1<<0) +#define ACTION_LIST_ALL (1<<1) static const struct option config_options[] = { OPT_GROUP("Action"), OPT_BIT('l', "list", &actions, "show current config variables", ACTION_LIST), + OPT_BIT('a', "list-all", &actions, + "show current and all possible config variables with default values", ACTION_LIST_ALL), OPT_END() }; @@ -516,6 +519,45 @@ static int collect_current_config(const char *var, const char *value, normalize_value(section_name, name, value)); } +static int show_all_config(void) +{ + int i; + bool has_config; + struct config_section *section_node; + struct config_element *element_node; + + for (i = 0; default_configsets[i].section_name != NULL; i++) { + find_config(§ion_node, &element_node, + default_configsets[i].section_name, default_configsets[i].name); + + if (!element_node) + printf("%s.%s=%s\n", default_configsets[i].section_name, + default_configsets[i].name, default_configsets[i].value); + else + printf("%s.%s=%s\n", section_node->name, + element_node->name, element_node->value); + } + + /* Print config variables the default configsets haven't */ + list_for_each_entry(section_node, §ions, list) { + list_for_each_entry(element_node, §ion_node->element_head, list) { + has_config = false; + for (i = 0; default_configsets[i].section_name != NULL; i++) { + if (!strcmp(default_configsets[i].section_name, section_node->name) + && !strcmp(default_configsets[i].name, element_node->name)) { + has_config = true; + break; + } + } + if (!has_config) + printf("%s.%s=%s\n", section_node->name, + element_node->name, element_node->value); + } + } + + return 0; +} + static int perf_configset_with_option(configset_fn_t fn, const char *var, char *value) { char *section_name; @@ -585,6 +627,12 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) else goto out_err; goto out; + case ACTION_LIST_ALL: + if (argc == 0) + ret = show_all_config(); + else + goto out_err; + goto out; default: if (!has_option && argc == 0) { ret = perf_config(show_config, NULL); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] perf tools: modify error code when perf_session__new() fail.
Because perf_session__new() could fail for more reasons than just ENOMEM, I modified error code(ENOMEM or EINVAL) into -1. Signed-off-by: Taeung Song --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-evlist.c| 2 +- tools/perf/builtin-inject.c| 2 +- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-kvm.c | 4 ++-- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-mem.c | 2 +- tools/perf/builtin-report.c| 2 +- tools/perf/builtin-script.c| 2 +- tools/perf/builtin-timechart.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index d4da692..be59394 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -340,7 +340,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) annotate.session = perf_session__new(&file, false, &annotate.tool); if (annotate.session == NULL) - return -ENOMEM; + return -1; symbol_conf.priv_size = sizeof(struct annotation); symbol_conf.try_vmlinux_path = true; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 190d0b6..a3ce19f 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -683,7 +683,7 @@ static int __cmd_diff(void) d->session = perf_session__new(&d->file, false, &tool); if (!d->session) { pr_err("Failed to open %s\n", d->file.path); - ret = -ENOMEM; + ret = -1; goto out_delete; } diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 66e12f5..0f93f85 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -28,7 +28,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details session = perf_session__new(&file, 0, NULL); if (session == NULL) - return -ENOMEM; + return -1; evlist__for_each(session->evlist, pos) perf_evsel__fprintf(pos, details, stdout); diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 3a62b6b..de99ca1 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -460,7 +460,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) file.path = inject.input_name; inject.session = perf_session__new(&file, true, &inject.tool); if (inject.session == NULL) - return -ENOMEM; + return -1; if (symbol__init(&inject.session->header.env) < 0) return -1; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 2376218..f295141 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -698,7 +698,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) session = perf_session__new(&file, false, &perf_kmem); if (session == NULL) - return -ENOMEM; + return -1; symbol__init(&session->header.env); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index f5d3ae4..fd84d47 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1062,7 +1062,7 @@ static int read_events(struct perf_kvm_stat *kvm) kvm->session = perf_session__new(&file, false, &kvm->tool); if (!kvm->session) { pr_err("Initializing perf session failed\n"); - return -EINVAL; + return -1; } symbol__init(&kvm->session->header.env); @@ -1365,7 +1365,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, */ kvm->session = perf_session__new(&file, false, &kvm->tool); if (kvm->session == NULL) { - err = -ENOMEM; + err = -1; goto out; } kvm->session->evlist = kvm->evlist; diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 92790ed..e7ec715 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -862,7 +862,7 @@ static int __cmd_report(bool display_info) session = perf_session__new(&file, false, &eops); if (!session) { pr_err("Initializing perf session failed\n"); - return -ENOMEM; + return -1; } symbol__init(&session->header.env); diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 8b4a87f..24db6ff 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -
[PATCH] perf top: Add a visual cue for toggle zeroing of samples
When 'perf top' is run, one can't easily find a difference between -z option and normal output. So I added a visual cue to know whether it is the zeroing or not. Signed-off-by: Taeung Song --- tools/perf/ui/browsers/hists.c | 38 ++ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 8f60a97..be49363 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -35,7 +35,9 @@ struct hist_browser { extern void hist_browser__init_hpp(void); -static int hists__browser_title(struct hists *hists, char *bf, size_t size); +static int hists__browser_title(struct hists *hists, + struct hist_browser_timer *hbt, + char *bf, size_t size); static void hist_browser__update_nr_entries(struct hist_browser *hb); static struct rb_node *hists__filter_entries(struct rb_node *nd, @@ -390,7 +392,7 @@ static int hist_browser__run(struct hist_browser *browser, browser->b.entries = &browser->hists->entries; browser->b.nr_entries = hist_browser__nr_entries(browser); - hists__browser_title(browser->hists, title, sizeof(title)); + hists__browser_title(browser->hists, hbt, title, sizeof(title)); if (ui_browser__show(&browser->b, title, "Press '?' for help on key bindings") < 0) @@ -417,7 +419,8 @@ static int hist_browser__run(struct hist_browser *browser, ui_browser__warn_lost_events(&browser->b); } - hists__browser_title(browser->hists, title, sizeof(title)); + hists__browser_title(browser->hists, +hbt, title, sizeof(title)); ui_browser__show_title(&browser->b, title); continue; } @@ -1204,7 +1207,16 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser return browser->he_selection->thread; } -static int hists__browser_title(struct hists *hists, char *bf, size_t size) +/* Check whether the browser is for 'top' or 'report' */ +static inline bool is_report_browser(void *timer) +{ + return timer == NULL; +} + +static int hists__browser_title(struct hists *hists, + struct hist_browser_timer *hbt, + char *bf, + size_t size) { char unit; int printed; @@ -1241,7 +1253,7 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size) nr_samples = convert_unit(nr_samples, &unit); printed = scnprintf(bf, size, - "Samples: %lu%c of event '%s', Event count (approx.): %lu", + "Samples: %lu%c of event z'%s', Event count (approx.): %lu", nr_samples, unit, ev_name, nr_events); @@ -1255,7 +1267,15 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size) thread->tid); if (dso) printed += scnprintf(bf + printed, size - printed, - ", DSO: %s", dso->short_name); +", DSO: %s", dso->short_name); + if (!is_report_browser(hbt)) { + struct perf_top *top = hbt->arg; + + if (top->zero) + printed += scnprintf(bf + printed, size - printed, +", [z]", ""); + } + return printed; } @@ -1267,12 +1287,6 @@ static inline void free_popup_options(char **options, int n) zfree(&options[i]); } -/* Check whether the browser is for 'top' or 'report' */ -static inline bool is_report_browser(void *timer) -{ - return timer == NULL; -} - /* * Only runtime switching of perf data file will make "input_name" point * to a malloced buffer. So add "is_input_name_malloced" flag to decide -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] perf top: Add a visual cue for toggle zeroing of samples
When 'perf top' is run, one can't easily find a difference between -z option and normal output. So I added a visual cue to know whether it is the zeroing or not. Signed-off-by: Taeung Song --- tools/perf/PERF-FEATURES | 1 + tools/perf/ui/browsers/hists.c | 34 -- 2 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 tools/perf/PERF-FEATURES diff --git a/tools/perf/PERF-FEATURES b/tools/perf/PERF-FEATURES new file mode 100644 index 000..bf2723d --- /dev/null +++ b/tools/perf/PERF-FEATURES @@ -0,0 +1 @@ +feature-dwarf(1) feature-glibc(1) feature-gtk2(0) feature-libaudit(1) feature-libbfd(0) feature-libelf(1) feature-libnuma(1) feature-libperl(1) feature-libpython(0) feature-libslang(1) feature-libunwind(1) feature-libdw-dwarf-unwind(1) dwarf-post-unwind(libunwind) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 8f60a97..6af157c 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -35,7 +35,9 @@ struct hist_browser { extern void hist_browser__init_hpp(void); -static int hists__browser_title(struct hists *hists, char *bf, size_t size); +static int hists__browser_title(struct hists *hists, + struct hist_browser_timer *hbt, + char *bf, size_t size); static void hist_browser__update_nr_entries(struct hist_browser *hb); static struct rb_node *hists__filter_entries(struct rb_node *nd, @@ -390,7 +392,7 @@ static int hist_browser__run(struct hist_browser *browser, browser->b.entries = &browser->hists->entries; browser->b.nr_entries = hist_browser__nr_entries(browser); - hists__browser_title(browser->hists, title, sizeof(title)); + hists__browser_title(browser->hists, hbt, title, sizeof(title)); if (ui_browser__show(&browser->b, title, "Press '?' for help on key bindings") < 0) @@ -417,7 +419,8 @@ static int hist_browser__run(struct hist_browser *browser, ui_browser__warn_lost_events(&browser->b); } - hists__browser_title(browser->hists, title, sizeof(title)); + hists__browser_title(browser->hists, +hbt, title, sizeof(title)); ui_browser__show_title(&browser->b, title); continue; } @@ -1204,7 +1207,16 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser return browser->he_selection->thread; } -static int hists__browser_title(struct hists *hists, char *bf, size_t size) +/* Check whether the browser is for 'top' or 'report' */ +static inline bool is_report_browser(void *timer) +{ + return timer == NULL; +} + +static int hists__browser_title(struct hists *hists, + struct hist_browser_timer *hbt, + char *bf, + size_t size) { char unit; int printed; @@ -1256,6 +1268,14 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size) if (dso) printed += scnprintf(bf + printed, size - printed, ", DSO: %s", dso->short_name); + if (!is_report_browser(hbt)) { + struct perf_top *top = hbt->arg; + + if (top->zero) + printed += scnprintf(bf + printed, size - printed, +", [z]", ""); + } + return printed; } @@ -1267,12 +1287,6 @@ static inline void free_popup_options(char **options, int n) zfree(&options[i]); } -/* Check whether the browser is for 'top' or 'report' */ -static inline bool is_report_browser(void *timer) -{ - return timer == NULL; -} - /* * Only runtime switching of perf data file will make "input_name" point * to a malloced buffer. So add "is_input_name_malloced" flag to decide -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] perf top: Add a visual cue for toggle zeroing of samples
When 'perf top' is run, one can't easily find a difference between -z option and normal output. So I added a visual cue to know whether it is the zeroing or not. Signed-off-by: Taeung Song --- tools/perf/ui/browsers/hists.c | 34 -- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 8f60a97..6af157c 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -35,7 +35,9 @@ struct hist_browser { extern void hist_browser__init_hpp(void); -static int hists__browser_title(struct hists *hists, char *bf, size_t size); +static int hists__browser_title(struct hists *hists, + struct hist_browser_timer *hbt, + char *bf, size_t size); static void hist_browser__update_nr_entries(struct hist_browser *hb); static struct rb_node *hists__filter_entries(struct rb_node *nd, @@ -390,7 +392,7 @@ static int hist_browser__run(struct hist_browser *browser, browser->b.entries = &browser->hists->entries; browser->b.nr_entries = hist_browser__nr_entries(browser); - hists__browser_title(browser->hists, title, sizeof(title)); + hists__browser_title(browser->hists, hbt, title, sizeof(title)); if (ui_browser__show(&browser->b, title, "Press '?' for help on key bindings") < 0) @@ -417,7 +419,8 @@ static int hist_browser__run(struct hist_browser *browser, ui_browser__warn_lost_events(&browser->b); } - hists__browser_title(browser->hists, title, sizeof(title)); + hists__browser_title(browser->hists, +hbt, title, sizeof(title)); ui_browser__show_title(&browser->b, title); continue; } @@ -1204,7 +1207,16 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser return browser->he_selection->thread; } -static int hists__browser_title(struct hists *hists, char *bf, size_t size) +/* Check whether the browser is for 'top' or 'report' */ +static inline bool is_report_browser(void *timer) +{ + return timer == NULL; +} + +static int hists__browser_title(struct hists *hists, + struct hist_browser_timer *hbt, + char *bf, + size_t size) { char unit; int printed; @@ -1256,6 +1268,14 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size) if (dso) printed += scnprintf(bf + printed, size - printed, ", DSO: %s", dso->short_name); + if (!is_report_browser(hbt)) { + struct perf_top *top = hbt->arg; + + if (top->zero) + printed += scnprintf(bf + printed, size - printed, +", [z]", ""); + } + return printed; } @@ -1267,12 +1287,6 @@ static inline void free_popup_options(char **options, int n) zfree(&options[i]); } -/* Check whether the browser is for 'top' or 'report' */ -static inline bool is_report_browser(void *timer) -{ - return timer == NULL; -} - /* * Only runtime switching of perf data file will make "input_name" point * to a malloced buffer. So add "is_input_name_malloced" flag to decide -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH resend] perf top: Add a visual cue for toggle zeroing of samples
When 'perf top' is run, one can't easily find a difference between -z option and normal output. So I added a visual cue to know whether it is the zeroing or not. Output is as below. Before: $ perf top Samples: 61K of event 'cycles', Event count (approx.): 3908136933 Overhead Shared Object Symbol 1.42% firefox [.] 0x00011e76 1.32% libpthread-2.17.so [.] pthread_mutex_lock If you press key 'z' or run with zero option like '$ perf top --zero', it is as below. After: Samples: 61K of event 'cycles', Event count (approx.): 3908136933 [z] Overhead Shared Object Symbol 1.42% firefox [.] 0x00011e76 1.32% libpthread-2.17.so [.] pthread_mutex_lock Signed-off-by: Taeung Song --- tools/perf/ui/browsers/hists.c | 32 ++-- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 8f60a97..79b66d0 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -35,7 +35,9 @@ struct hist_browser { extern void hist_browser__init_hpp(void); -static int hists__browser_title(struct hists *hists, char *bf, size_t size); +static int hists__browser_title(struct hists *hists, + struct hist_browser_timer *hbt, + char *bf, size_t size); static void hist_browser__update_nr_entries(struct hist_browser *hb); static struct rb_node *hists__filter_entries(struct rb_node *nd, @@ -390,7 +392,7 @@ static int hist_browser__run(struct hist_browser *browser, browser->b.entries = &browser->hists->entries; browser->b.nr_entries = hist_browser__nr_entries(browser); - hists__browser_title(browser->hists, title, sizeof(title)); + hists__browser_title(browser->hists, hbt, title, sizeof(title)); if (ui_browser__show(&browser->b, title, "Press '?' for help on key bindings") < 0) @@ -417,7 +419,8 @@ static int hist_browser__run(struct hist_browser *browser, ui_browser__warn_lost_events(&browser->b); } - hists__browser_title(browser->hists, title, sizeof(title)); + hists__browser_title(browser->hists, +hbt, title, sizeof(title)); ui_browser__show_title(&browser->b, title); continue; } @@ -1204,7 +1207,15 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser return browser->he_selection->thread; } -static int hists__browser_title(struct hists *hists, char *bf, size_t size) +/* Check whether the browser is for 'top' or 'report' */ +static inline bool is_report_browser(void *timer) +{ + return timer == NULL; +} + +static int hists__browser_title(struct hists *hists, + struct hist_browser_timer *hbt, + char *bf, size_t size) { char unit; int printed; @@ -1256,6 +1267,13 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size) if (dso) printed += scnprintf(bf + printed, size - printed, ", DSO: %s", dso->short_name); + if (!is_report_browser(hbt)) { + struct perf_top *top = hbt->arg; + + if (top->zero) + printed += scnprintf(bf + printed, size - printed, " [z]"); + } + return printed; } @@ -1267,12 +1285,6 @@ static inline void free_popup_options(char **options, int n) zfree(&options[i]); } -/* Check whether the browser is for 'top' or 'report' */ -static inline bool is_report_browser(void *timer) -{ - return timer == NULL; -} - /* * Only runtime switching of perf data file will make "input_name" point * to a malloced buffer. So add "is_input_name_malloced" flag to decide -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 0/5] perf tools: Add 'perf-config' command
So far, it is difficult that the state of perf configs is looked through and there's no knowing what kind of other variables except variables in perfconfig.example. Also perf configs can't be changed without manually modifying $HOME/.perfconfig or $(sysconfdir)/perfconfig file. So I suggest this patchset of the perf-config command which can list, get, set, remove perf configs or list with default config values as below. [PATCH v4 1/5] perf tools: Add 'perf-config' command [PATCH v4 2/5] perf config: Add '--system' and '--global' options to select which config file to be used [PATCH v4 3/5] perf config: Add functions which can get or set perf config variables [PATCH v4 4/5] perf config: Add a option 'list-all' to perf-config [PATCH v4 5/5] perf config: Add a option 'remove' to perf-config Changes in v4: - If some config value is default value, notice it is '(default)' as suggested by Jirka. (PATCH v4 3/5) - If there wasn't any perfconfig file, perf-config malfunctioned like Jirka pointed out. So add exception routine with '--global' and '--system' option which can select perf config file path. (PATCH v4 2/5) Changes in v3: - Add a config variable 'kmem.default' with a default value as suggested by Namhyung. (PATCH v3 2/5, PATCH v4 3/5) Changes in v2: - Change option name of listing all configs as '--list-all' instead of '--all' as suggested by Namhyung. (PATCH v2 3/4, PATCH v4 4/5) - Correct small infelicities or typing errors in a perf-config documention as suggested by Arnaldo. (PATCH v2 1/4, PATCH v4 1/5) - Declaration a global variable 'static struct default_configsets' has config variables with default values instead of using a 'util/PERFCONFIG-DEFAULT' file. (PATCH v2 3/4, PATCH v4 3/5) - Add a function to normalize a value and check data type of it. (PATCH v2 2/4, PATCH v4 3/5) - 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. (PATCH v2 2/4, PATCH v4 3/5) - If run perf-config command without any option, perf-config work as '--list'. (PATCH v2 1/4, PATCH v4 1/5) --- tools/perf/Build| 1 + tools/perf/Documentation/perf-config.txt| 407 tools/perf/Documentation/perfconfig.example | 73 ++- tools/perf/builtin-config.c | 718 tools/perf/builtin.h| 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 1 + tools/perf/util/cache.h | 19 + tools/perf/util/config.c| 29 +- 9 files changed, 1236 insertions(+), 14 deletions(-) create mode 100644 tools/perf/Documentation/perf-config.txt create mode 100644 tools/perf/builtin-config.c -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 1/5] perf tools: Add 'perf-config' command
The perf configuration file contains many variables which can make the perf command's action more effective. 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 and a document for it. perf config [options] display current perf config variables. # perf config or # perf config -l | --list Signed-off-by: Taeung Song --- tools/perf/Build| 1 + tools/perf/Documentation/perf-config.txt| 381 tools/perf/Documentation/perfconfig.example | 73 +- tools/perf/builtin-config.c | 76 ++ tools/perf/builtin.h| 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 1 + 7 files changed, 522 insertions(+), 12 deletions(-) create mode 100644 tools/perf/Documentation/perf-config.txt 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/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt new file mode 100644 index 000..1a339ea --- /dev/null +++ b/tools/perf/Documentation/perf-config.txt @@ -0,0 +1,381 @@ +perf-config(1) +== + +NAME + +perf-config - Get and set variables in a configuration file. + +SYNOPSIS + +[verse] +'perf config' -l | --list + +DESCRIPTION +--- +You can manage variables in a configuration file with this command. + +OPTIONS +--- + +-l:: +--list:: + Show current config variables with key and value into each sections. + +CONFIGURATION FILE +-- + +The Perf configuration file contains many variables which can make +the perf command's action more effective. +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. + +The variables are divided into sections. In each section, the variables +can are composed of a key and value. + +Syntax +~~ + +The file consists of sections and names. A section begins with +the name of the section in square brackets and continues until the next +section begins. Each variable have to belong to some section, which means +there must be a section header before the first setting of a variable, as below: +Each variable are in the form 'name = value'. + + [section] + name1 = value1 + name2 = value2 + +Section names are case sensitive and can contain any characters except +newline (doublequote `"` and backslash have to be escaped as `\"` and `\\`, +respectively). Section headers can't span multiple +lines. Variables may belong directly to a section. + +Example +~~~ + +Given a $HOME/.perfconfig like this: + +# +# This is the config file, and +# a '#' and ';' character indicates a comment +# + +[colors] + # Color variables + top = red, default + medium = green, default + normal = lightgray, default + selected = white, lightgray + code = blue, default + addr = magenta, default + root = white, blue + +[tui] + # Defaults if linked with libslang + report = on + annotate = on + top = on + +[buildid] + # Default, disable using /dev/null + dir = ~/.debug + +[annotate] + # Defaults + hide_src_code = false + use_offset = true + jump_arrows = true + show_nr_jumps = false + +[help] + # Format can be man, info, web or html + format = man + autocorrect = 0 + +[ui] + show-headers= true + +[call-graph] + # fp (framepointer), dwarf + record-mode = fp + print-type = graph + order = caller + sort-key = function + +Variables +~ + +colors.*:: + Color variables can customize colors of the output which is printed out + from ‘report’, ‘top’, ’annotate’ on tui. + Color variables are composed of foreground and background + and should have two values for them. If you want to keep as colors + of your terminal, you should use ‘default’ for the color value. + The color names that can be used are: + red, green, default, black, blue, white, magenta, lightgray + + colors.top:: + ‘top’ means a overhead percentage which is more than 5%. + And values of this variable specify colors of percentage. + Basic key values are foreground-color ’red’ and
[PATCH v4 4/5] perf config: Add a option 'list-all' to perf-config
A option 'list-all' is to display both current config variables and all possible config variables with default values. The syntax examples are like below perf config [options] display all perf config with default values. # perf config -a | --list-all Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 6 tools/perf/builtin-config.c | 48 2 files changed, 54 insertions(+) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index cd4b1a6..d8b3acc 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -11,6 +11,8 @@ SYNOPSIS 'perf config' [] [section.name[=value] ...] or 'perf config' [] -l | --list +or +'perf config' [] -a | --list-all DESCRIPTION --- @@ -31,6 +33,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 6d9f28c..f4a1569 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -23,6 +23,7 @@ static const char * const config_usage[] = { }; #define ACTION_LIST (1<<0) +#define ACTION_LIST_ALL (1<<1) static const struct option config_options[] = { OPT_GROUP("Config file location"), @@ -31,6 +32,8 @@ static const struct option config_options[] = { OPT_GROUP("Action"), OPT_BIT('l', "list", &actions, "show current config variables", ACTION_LIST), + OPT_BIT('a', "list-all", &actions, + "show current and all possible config variables with default values", ACTION_LIST_ALL), OPT_END() }; @@ -539,6 +542,45 @@ static int collect_current_config(const char *var, const char *value, normalize_value(section_name, name, value)); } +static int show_all_config(void) +{ + int i; + bool has_config; + struct config_section *section_node; + struct config_element *element_node; + + for (i = 0; default_configsets[i].section_name != NULL; i++) { + find_config(§ion_node, &element_node, + default_configsets[i].section_name, default_configsets[i].name); + + if (!element_node) + printf("%s.%s=%s\n", default_configsets[i].section_name, + default_configsets[i].name, default_configsets[i].value); + else + printf("%s.%s=%s\n", section_node->name, + element_node->name, element_node->value); + } + + /* Print config variables the default configsets haven't */ + list_for_each_entry(section_node, §ions, list) { + list_for_each_entry(element_node, §ion_node->element_head, list) { + has_config = false; + for (i = 0; default_configsets[i].section_name != NULL; i++) { + if (!strcmp(default_configsets[i].section_name, section_node->name) + && !strcmp(default_configsets[i].name, element_node->name)) { + has_config = true; + break; + } + } + if (!has_config) + printf("%s.%s=%s\n", section_node->name, + element_node->name, element_node->value); + } + } + + return 0; +} + static int perf_configset_with_option(configset_fn_t fn, const char *var, char *value) { char *section_name; @@ -617,6 +659,12 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) else goto out_err; goto out; + case ACTION_LIST_ALL: + if (argc == 0) + ret = show_all_config(); + else + goto out_err; + goto out; default: if ((!has_option || use_global_config || use_system_config) && argc == 0) { -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 3/5] perf config: Add functions which can get or set perf config variables
This patch consists of functions which can get, set specific config variables. For the syntax examples, perf config [options] [section.name[=value] ...] display key-value pairs of specific config variables # perf config report.queue-size report.children set specific config variables # perf config report.queue-size=100M report.children=true Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 2 + tools/perf/builtin-config.c | 560 ++- tools/perf/util/cache.h | 17 + tools/perf/util/config.c | 25 ++ 4 files changed, 602 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index f1e50b3..cd4b1a6 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' [] [section.name[=value] ...] +or 'perf config' [] -l | --list DESCRIPTION diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 27609bd..6d9f28c 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -18,7 +18,7 @@ static bool use_system_config, use_global_config; static const char *config_file_name; static const char * const config_usage[] = { - "perf config [options]", + "perf config [options] [section.name[=value] ...]", NULL }; @@ -34,6 +34,353 @@ static const struct option config_options[] = { OPT_END() }; +/* section names */ +#define COLORS "colors" +#define TUI "tui" +#define BUILDID "buildid" +#define ANNOTATE "annotate" +#define GTK "gtk" +#define PAGER "pager" +#define HELP "help" +#define HIST "hist" +#define UI "ui" +#define CALL_GRAPH "call-graph" +#define REPORT "report" +#define TOP "top" +#define MAN "man" +#define KMEM "kmem" + +/* config variable types */ +#define TYPE_INT "int" +#define TYPE_LONG "long" +#define TYPE_DIRNAME "dirname" +#define TYPE_BOOL "bool" +#define TYPE_ON_OFF "on_off" + +static struct default_configset { + const char *section_name; + const char *name, *value, *type; + +} default_configsets[] = { + { + .section_name = COLORS, + .name = "top", + .value = "red, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "medium", + .value = "green, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "normal", + .value = "lightgray, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "selected", + .value = "white, lightgray", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "code", + .value = "blue, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "addr", + .value = "magenta, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "root", + .value = "white, blue", + .type = NULL, + }, + { + .section_name = TUI, + .name = "report", + .value = "on", + .type = TYPE_ON_OFF, + }, + { + .section_name = TUI, + .name = "annotate", + .value = "on", + .type = TYPE_ON_OFF, + }, + { + .section_name = TUI, + .name = "top", + .value = "on", + .type = TYPE_ON_OFF, + }, + { + .section_name = BUILDID, + .name = "dir", + .value = "~/.debug", + .type = TYPE_DIRNAME, + }, + { + .section_name = ANNOTATE, + .name = "hide_src_code", + .value = "false", + .type = TYPE_BOOL, + }, + { + .section_name = ANNOTATE, + .name = "use_offset", + .value = "true", + .type = TYPE_BOOL, + }, + { + .section_name = ANNOTATE, +
[PATCH v4 5/5] perf config: Add a option 'remove' to perf-config
A option 'remove' is to remove specific config variables. For the syntax examples, # perf config -r | --remove [section.name ...] Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 6 ++ tools/perf/builtin-config.c | 25 - 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index d8b3acc..416637b 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -13,6 +13,8 @@ or 'perf config' [] -l | --list or 'perf config' [] -a | --list-all +or +'perf config' [] -r | --remove [section.name ...] DESCRIPTION --- @@ -37,6 +39,10 @@ OPTIONS --list-all:: Show current and all possible config variables with default values. +-r:: +--remove:: + Remove specific config variables. + CONFIGURATION FILE -- diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index f4a1569..74fcedc 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -24,6 +24,7 @@ static const char * const config_usage[] = { #define ACTION_LIST (1<<0) #define ACTION_LIST_ALL (1<<1) +#define ACTION_REMOVE (1<<2) static const struct option config_options[] = { OPT_GROUP("Config file location"), @@ -34,6 +35,8 @@ static const struct option config_options[] = { "show current config variables", ACTION_LIST), OPT_BIT('a', "list-all", &actions, "show current and all possible config variables with default values", ACTION_LIST_ALL), + OPT_BIT('r', "remove", &actions, + "remove specific variables: [section.name ...]", ACTION_REMOVE), OPT_END() }; @@ -484,7 +487,15 @@ static int set_config(const char *section_name, const char *name, char *value) struct config_element *element_node = NULL; find_config(§ion_node, &element_node, section_name, name); - if (value != NULL) { + if (!value) { + /* value == NULL means remove the variable */ + if (section_node && element_node) { + if (!element_node->value) + free(element_node->value); + element_node->value = NULL; + } else + pr_err("Error: Failed to find the variable.\n"); + } else { value = normalize_value(section_name, name, value); /* if there isn't existent section, add a new section */ @@ -665,6 +676,18 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) else goto out_err; goto out; + case ACTION_REMOVE: + for (i = 0; argv[i]; i++) { + if (value == NULL) + ret = perf_configset_with_option(set_config, argv[i], NULL); + else { + pr_err("invalid key: %s\n", argv[i]); + return -1; + } + if (ret < 0) + goto out; + } + goto out; default: if ((!has_option || use_global_config || use_system_config) && argc == 0) { -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 2/5] perf config: Add '--system' and '--global' options to select which config file is used
Which config file is used is decided in only perf_config(). And a perf-confg command depend on perf_config() getting config file path. So add '--system' and '--global' options to select which config file to be used without perf_config(). If file-options isn't used, default config file path is $HOME/.perfconfig. Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 14 +- tools/perf/builtin-config.c | 21 ++--- tools/perf/util/cache.h | 2 ++ tools/perf/util/config.c | 4 ++-- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 1a339ea..f1e50b3 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' [] -l | --list DESCRIPTION --- @@ -21,6 +21,14 @@ OPTIONS --list:: Show current config variables with key and value into each sections. +--global:: + For writing and reading options: write to global + '$HOME/.perfconfig' file or read it. + +--system:: + For writing and reading options: write to system-wide + '$(sysconfdir)/perfconfig' or read it. + CONFIGURATION FILE -- @@ -33,6 +41,10 @@ store a system-wide default configuration. The variables are divided into sections. In each section, the variables can are composed of a key and value. +When reading or writing, the values are read from the system and global +configuration files by default, and options '--system' and '--global' +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 f0541b8..27609bd 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -14,6 +14,8 @@ #include "util/debug.h" static int actions; +static bool use_system_config, use_global_config; +static const char *config_file_name; static const char * const config_usage[] = { "perf config [options]", @@ -23,6 +25,9 @@ static const char * const config_usage[] = { #define ACTION_LIST (1<<0) static const struct option config_options[] = { + OPT_GROUP("Config file location"), + OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"), + OPT_BOOLEAN(0, "global", &use_global_config, "use global config file"), OPT_GROUP("Action"), OPT_BIT('l', "list", &actions, "show current config variables", ACTION_LIST), @@ -53,16 +58,26 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) else has_option = false; + if (use_system_config && use_global_config) { + pr_err("Error: only one config file at a time\n"); + usage_with_options(config_usage, config_options); + return -1; + } else if (use_global_config || (!use_system_config && !use_global_config)) + config_file_name = mkpath("%s/.perfconfig", getenv("HOME")); + else if (use_system_config) + config_file_name = perf_etc_perfconfig(); + switch (actions) { case ACTION_LIST: if (argc == 0) - ret = perf_config(show_config, NULL); + ret = perf_config_from_file(show_config, config_file_name, NULL); else goto out_err; goto out; default: - if (!has_option && argc == 0) { - ret = perf_config(show_config, NULL); + if ((!has_option || use_global_config || use_system_config) + && argc == 0) { + ret = perf_config_from_file(show_config, config_file_name, NULL); goto out; } else goto out_err; diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index c861373..bad3e4e 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -22,11 +22,13 @@ 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 *); +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 ch
[PATCH v5 0/6] perf tools: Add 'perf-config' command
So far, it is difficult that the state of perf configs is looked through and there's no knowing what kind of other variables except variables in perfconfig.example. Also perf configs can't be changed without manually modifying $HOME/.perfconfig or $(sysconfdir)/perfconfig file. So I suggest this patchset of the perf-config command which can list, get, set, remove perf configs or list with default config values as below. [PATCH v5 1/6] perf tools: Add 'perf-config' command [PATCH v5 2/6] perf config: Add '--system' and '--user' options to select which config file to be used [PATCH v5 3/6] perf config: Add a option 'list-all' to perf-config [PATCH v5 4/6] perf config: Add 'get' functionality [PATCH v5 5/6] perf config: Add 'set' feature [PATCH v5 6/6] perf config: Add a option 'remove' to perf-config Changes in v5: - Simplify the switch statement in cmd_config() - Set a config file path with '--system' or '--user' instead of '--global' or '--system' as suggested by Namhyung. (PATCH v5 2/6) - The patch about 'get' and 'set 'split into two patchs as suggested by Namhyung. (PATCH v5 4/6, PATCH v5 5/6) Changes in v4: - If some config value is default value, notice it is '(default)' as suggested by Jirka. (PATCH v4 3/5) - If there wasn't any perfconfig file, perf-config malfunctioned like Jirka pointed out. So add exception routine with '--global' and '--system' option which can select perf config file path. (PATCH v4 2/5) Changes in v3: - Add a config variable 'kmem.default' with a default value as suggested by Namhyung. (PATCH v3 2/5, PATCH v4 3/5) Changes in v2: - Change option name of listing all configs as '--list-all' instead of '--all' as suggested by Namhyung. (PATCH v2 3/4, PATCH v4 4/5) - Correct small infelicities or typing errors in a perf-config documention as suggested by Arnaldo. (PATCH v2 1/4, PATCH v4 1/5) - Declaration a global variable 'static struct default_configsets' has config variables with default values instead of using a 'util/PERFCONFIG-DEFAULT' file. (PATCH v2 3/4, PATCH v4 3/5) - Add a function to normalize a value and check data type of it. (PATCH v2 2/4, PATCH v4 3/5) - 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. (PATCH v2 2/4, PATCH v4 3/5) - If run perf-config command without any option, perf-config work as '--list'. (PATCH v2 1/4, PATCH v4 1/5) --- tools/perf/Build| 1 + tools/perf/Documentation/perf-config.txt| 407 tools/perf/Documentation/perfconfig.example | 73 ++- tools/perf/builtin-config.c | 708 tools/perf/builtin.h| 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 1 + tools/perf/util/cache.h | 19 + tools/perf/util/config.c| 31 +- 9 files changed, 1228 insertions(+), 14 deletions(-) create mode 100644 tools/perf/Documentation/perf-config.txt create mode 100644 tools/perf/builtin-config.c -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 1/6] perf tools: Add 'perf-config' command
The perf configuration file contains many variables which can make the perf command's action more effective. 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 and a document for it. perf config [options] display current perf config variables. # perf config or # perf config -l | --list Signed-off-by: Taeung Song --- tools/perf/Build| 1 + tools/perf/Documentation/perf-config.txt| 381 tools/perf/Documentation/perfconfig.example | 73 +- tools/perf/builtin-config.c | 61 + tools/perf/builtin.h| 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 1 + 7 files changed, 507 insertions(+), 12 deletions(-) create mode 100644 tools/perf/Documentation/perf-config.txt 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/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt new file mode 100644 index 000..a3a12cc --- /dev/null +++ b/tools/perf/Documentation/perf-config.txt @@ -0,0 +1,381 @@ +perf-config(1) +== + +NAME + +perf-config - Get and set variables in a configuration file. + +SYNOPSIS + +[verse] +'perf config' -l | --list + +DESCRIPTION +--- +You can manage variables in a configuration file with this command. + +OPTIONS +--- + +-l:: +--list:: + Show current config variables with key and value into each sections. + +CONFIGURATION FILE +-- + +The Perf configuration file contains many variables which can make +the perf command's action more effective. +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. + +The variables are divided into sections. In each section, the variables +can are composed of a key and value. + +Syntax +~~ + +The file consists of sections and names. A section begins with +the name of the section in square brackets and continues until the next +section begins. Each variable have to belong to some section, which means +there must be a section header before the first setting of a variable, as below: +Each variable are in the form 'name = value'. + + [section] + name1 = value1 + name2 = value2 + +Section names are case sensitive and can contain any characters except +newline (doublequote `"` and backslash have to be escaped as `\"` and `\\`, +respectively). Section headers can't span multiple +lines. Variables may belong directly to a section. + +Example +~~~ + +Given a $HOME/.perfconfig like this: + +# +# This is the config file, and +# a '#' and ';' character indicates a comment +# + +[colors] + # Color variables + top = red, default + medium = green, default + normal = lightgray, default + selected = white, lightgray + code = blue, default + addr = magenta, default + root = white, blue + +[tui] + # Defaults if linked with libslang + report = on + annotate = on + top = on + +[buildid] + # Default, disable using /dev/null + dir = ~/.debug + +[annotate] + # Defaults + hide_src_code = false + use_offset = true + jump_arrows = true + show_nr_jumps = false + +[help] + # Format can be man, info, web or html + format = man + autocorrect = 0 + +[ui] + show-headers= true + +[call-graph] + # fp (framepointer), dwarf + record-mode = fp + print-type = graph + order = caller + sort-key = function + +Variables +~ + +colors.*:: + Color variables can customize colors of the output which is printed out + from ‘report’, ‘top’, ’annotate’ on tui. + Color variables are composed of foreground and background + and should have two values for them. If you want to keep as colors + of your terminal, you should use ‘default’ for the color value. + The color names that can be used are: + red, green, default, black, blue, white, magenta, lightgray + + colors.top:: + ‘top’ means a overhead percentage which is more than 5%. + And values of this variable specify colors of percentage. + Basic key values are foreground-color ’red’ and
[PATCH v5 3/6] perf config: Add a option 'list-all' to perf-config
A option 'list-all' is to display both current config variables and all possible config variables with default values. The syntax examples are like below perf config [options] display all perf config with default values. # perf config -a | --list-all Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 6 + tools/perf/builtin-config.c | 490 ++- tools/perf/util/cache.h | 15 + 3 files changed, 510 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index b2abb16..d95baad 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -9,6 +9,8 @@ SYNOPSIS [verse] 'perf config' [] -l | --list +or +'perf config' [] -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 df70b90..ac13aaf 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 = 1, + ACTION_LIST_ALL } actions; static const struct option config_options[] = { @@ -32,9 +33,362 @@ static const struct option config_options[] = { OPT_GROUP("Action"), 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_END() }; +/* section names */ +#define COLORS "colors" +#define TUI "tui" +#define BUILDID "buildid" +#define ANNOTATE "annotate" +#define GTK "gtk" +#define PAGER "pager" +#define HELP "help" +#define HIST "hist" +#define UI "ui" +#define CALL_GRAPH "call-graph" +#define REPORT "report" +#define TOP "top" +#define MAN "man" +#define KMEM "kmem" + +/* config variable types */ +#define TYPE_INT "int" +#define TYPE_LONG "long" +#define TYPE_DIRNAME "dirname" +#define TYPE_BOOL "bool" +#define TYPE_ON_OFF "on_off" + +static struct default_configset { + const char *section_name; + const char *name, *value, *type; + +} default_configsets[] = { + { + .section_name = COLORS, + .name = "top", + .value = "red, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "medium", + .value = "green, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "normal", + .value = "lightgray, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "selected", + .value = "white, lightgray", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "code", + .value = "blue, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "addr", + .value = "magenta, default", + .type = NULL, + }, + { + .section_name = COLORS, + .name = "root", + .value = "white, blue", + .type = NULL, + }, + { + .section_name = TUI, + .name = "report", + .value = "on", + .type = TYPE_ON_OFF, + }, + { + .section_name = TUI, + .name = "annotate", + .value = "on", + .type = TYPE_ON_OFF, + }, + { + .section_name = TUI, + .name = "top", + .value = "on", + .type = TYPE_ON_OFF, + }, + { + .section_name = BUILDID, + .name = "dir", + .value = "~/.debug", + .type = TYPE_DIRNAME, + }, + { +
[PATCH v5 6/6] perf config: Add a option 'remove' to perf-config
A option 'remove' is to remove specific config variables. For the syntax examples, # perf config -r | --remove [section.name ...] Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 6 ++ tools/perf/builtin-config.c | 26 -- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 9c95af8..cfa6013 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -13,6 +13,8 @@ or 'perf config' [] -l | --list or 'perf config' [] -a | --list-all +or +'perf config' [] -r | --remove [section.name ...] DESCRIPTION --- @@ -37,6 +39,10 @@ OPTIONS --list-all:: Show current and all possible config variables with default values. +-r:: +--remove:: + Remove specific config variables. + CONFIGURATION FILE -- diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index d5cc3e8..8d50637 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_LIST_ALL, + ACTION_REMOVE } actions; static const struct option config_options[] = { @@ -36,6 +37,8 @@ static const 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('r', "remove", &actions, +"remove specific variables: [section.name ...]", ACTION_REMOVE), OPT_END() }; @@ -495,7 +498,14 @@ static int set_config(const char *section_name, const char *name, char *value) struct config_element *element_node = NULL; find_config(§ion_node, &element_node, section_name, name); - if (value != NULL) { + if (!value) { + /* value == NULL means remove the variable */ + if (section_node && element_node) { + if (!element_node->value) + free(element_node->value); + element_node->value = NULL; + } + } else { value = normalize_value(section_name, name, value); /* if there isn't existent section, add a new section */ @@ -651,6 +661,18 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) perf_config_from_file(collect_current_config, config_file_name, NULL); switch (actions) { + case ACTION_REMOVE: + if (argc) { + for (i = 0; argv[i]; i++) { + ret = perf_configset_with_option(set_config, argv[i], NULL); + if (ret < 0) + goto out_err; + } + } else { + pr_err("Error: wrong number of arguments\n"); + goto out_err; + } + break; case ACTION_LIST_ALL: if (argc == 0) { ret = show_all_config(); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 4/6] perf config: Add 'get' functionality
This patch consists of functions which can get specific config variables. For the syntax examples, perf config [options] [section.name ...] display key-value pairs of specific config variables # perf config report.queue-size report.children Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 2 + tools/perf/builtin-config.c | 79 ++-- tools/perf/util/cache.h | 1 + 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index d95baad..691d52b 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' [] [section.name ...] +or 'perf config' [] -l | --list or 'perf config' [] -a | --list-all diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index ac13aaf..0f2193a 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -17,7 +17,7 @@ static bool use_system_config, use_user_config; static const char *config_file_name; static const char * const config_usage[] = { - "perf config [options]", + "perf config [options] [section.name ...]", NULL }; @@ -412,6 +412,37 @@ static void find_config(struct config_section **section_node, *element_node = NULL; } +static int show_spec_config(const char *section_name, const char *name) +{ + int i; + struct config_section *section_node = NULL; + struct config_element *element_node = NULL; + char key[BUFSIZ]; + + find_config(§ion_node, &element_node, section_name, name); + + if (section_node && element_node) { + scnprintf(key, sizeof(key), "%s.%s", + section_node->name, element_node->name); + return show_config(key, element_node->value, NULL); + } + + for (i = 0; default_configsets[i].section_name != NULL; i++) { + struct default_configset *config = &default_configsets[i]; + + if (!strcmp(config->section_name, section_name) && + !strcmp(config->name, name)) { + printf("%s.%s=%s (default)\n", config->section_name, + config->name, config->value); + return 0; + } + } + + pr_err("Error: %s.%s: failed to find the variable.\n", section_name, name); + + return 0; +} + static char *normalize_value(const char *section_name, const char *name, const char *value) { int i, ret = 0; @@ -526,9 +557,44 @@ static int show_all_config(void) return 0; } +static int perf_configset_with_option(configset_fn_t fn, const char *var) +{ + char *section_name; + char *name; + const char *last_dot; + char *key = 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); + return -1; + } + if (!last_dot[1]) { + pr_err("The config varible does not contain variable name: %s\n", key); + return -1; + } + + section_name = strsep(&key, "."); + name = strsep(&key, "."); + free(key); + + return fn(section_name, name); + + pr_err("invalid key: %s\n", var); + return -1; +} + int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) { - int ret = 0; + int i, ret = 0; argc = parse_options(argc, argv, config_options, config_usage, PARSE_OPT_STOP_AT_NON_OPTION); @@ -552,10 +618,17 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) break; } case ACTION_LIST: - default: if (argc) { pr_err("Error: unknown argument\n"); goto out_err; + } + default: + if (argc) { + for (i = 0; argv[i]; i++) { + ret = perf_configset_with_option(show_spec_config, argv[i]); + if (ret < 0) + break; + }
[PATCH v5 2/6] perf config: Add '--system' and '--user' options to select which config file is used
Which config file is used is decided in only perf_config(). And a perf-confg command depend on perf_config() getting config file path. So add '--system' and '--user' options to select which config file to be used without perf_config(). If file-options isn't used, default config file path is $HOME/.perfconfig. Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 14 +- tools/perf/builtin-config.c | 23 +-- tools/perf/util/cache.h | 2 ++ tools/perf/util/config.c | 4 ++-- 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index a3a12cc..b2abb16 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' [] -l | --list DESCRIPTION --- @@ -21,6 +21,14 @@ OPTIONS --list:: Show current config variables with key and value into each 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 -- @@ -33,6 +41,10 @@ store a system-wide default configuration. The variables are divided into sections. In each section, the variables can are composed of a key and value. +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 02c2ba2..df70b90 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -13,6 +13,9 @@ #include "util/util.h" #include "util/debug.h" +static bool use_system_config, use_user_config; +static const char *config_file_name; + static const char * const config_usage[] = { "perf config [options]", NULL @@ -23,6 +26,9 @@ enum actions { } actions; static const struct option config_options[] = { + OPT_GROUP("Config file location"), + OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"), + OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"), OPT_GROUP("Action"), OPT_SET_UINT('l', "list", &actions, "show current config variables", ACTION_LIST), @@ -47,15 +53,28 @@ 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"); + goto out_err; + } + config_file_name = mkpath("%s/.perfconfig", getenv("HOME")); + if (use_system_config || (!use_user_config && + access(config_file_name, R_OK) == -1)) + config_file_name = perf_etc_perfconfig(); + switch (actions) { case ACTION_LIST: default: if (argc) { pr_err("Error: unknown argument\n"); - usage_with_options(config_usage, config_options); + goto out_err; } else - ret = perf_config(show_config, NULL); + ret = perf_config_from_file(show_config, config_file_name, NULL); } return ret; + +out_err: + usage_with_options(config_usage, config_options); + return -1; } diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index c861373..bad3e4e 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -22,11 +22,13 @@ 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 *); +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 *); 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
[PATCH v5 5/6] perf config: Add 'set' feature
This patch consists of functions which can set specific config variables. For the syntax examples, perf config [options] [section.name[=value] ...] set specific config variables # perf config report.queue-size=100M report.children=true Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 2 +- tools/perf/builtin-config.c | 55 +--- tools/perf/util/cache.h | 3 +- tools/perf/util/config.c | 27 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 691d52b..9c95af8 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' [] [section.name ...] +'perf config' [] [section.name[=value] ...] or 'perf config' [] -l | --list or diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 0f2193a..d5cc3e8 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -17,7 +17,7 @@ static bool use_system_config, use_user_config; static const char *config_file_name; static const char * const config_usage[] = { - "perf config [options] [section.name ...]", + "perf config [options] [section.name[=value] ...]", NULL }; @@ -412,7 +412,8 @@ static void find_config(struct config_section **section_node, *element_node = NULL; } -static int show_spec_config(const char *section_name, const char *name) +static int show_spec_config(const char *section_name, const char *name, + char *value __maybe_unused) { int i; struct config_section *section_node = NULL; @@ -488,6 +489,34 @@ static char *normalize_value(const char *section_name, const char *name, const c return normalized; } +static int set_config(const char *section_name, const char *name, char *value) +{ + struct config_section *section_node = NULL; + struct config_element *element_node = NULL; + + find_config(§ion_node, &element_node, section_name, name); + if (value != NULL) { + value = normalize_value(section_name, name, value); + + /* if there isn't existent section, add a new section */ + if (!section_node) { + section_node = init_section(section_name); + if (!section_node) + return -1; + list_add_tail(§ion_node->list, §ions); + } + /* if nothing to replace, add a new element which contains key-value pair. */ + if (!element_node) { + add_element(§ion_node->element_head, name, value); + } else { + free(element_node->value); + element_node->value = value; + } + } + + return perf_configset_write_in_full(config_file_name); +} + static int collect_current_config(const char *var, const char *value, void *cb __maybe_unused) { @@ -557,7 +586,7 @@ static int show_all_config(void) return 0; } -static int perf_configset_with_option(configset_fn_t fn, const char *var) +static int perf_configset_with_option(configset_fn_t fn, const char *var, char *value) { char *section_name; char *name; @@ -585,8 +614,18 @@ static int perf_configset_with_option(configset_fn_t fn, const char *var) section_name = strsep(&key, "."); name = strsep(&key, "."); free(key); + if (!value) { + /* do nothing */ + } else if (!strcmp(value, "=")) { + pr_err("The config variable does not contain a value: %s.%s\n", + section_name, name); + return -1; + } else { + value++; + name = strsep(&name, "="); + } - return fn(section_name, name); + return fn(section_name, name, value); pr_err("invalid key: %s\n", var); return -1; @@ -625,7 +664,13 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) default: if (argc) { for (i = 0; argv[i]; i++) { - ret = perf_configset_with_option(show_spec_config, argv[i]); + char *value = strchr(argv[i], '='); + if (value == NULL) + ret = perf_configset_with_option(show_spec_config, +
[PATCH v8 1/4] perf config: Introduce perf_config_set class
This infrastructure code was designed for upcoming features of perf-config. That collect config key-value pairs from user and system config files (i.e. user wide ~/.perfconfig and system wide $(sysconfdir)/perfconfig) to manage perf's configs. Reviewed-by: Masami Hiramatsu Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/util/config.c | 173 +++ tools/perf/util/config.h | 26 +++ 2 files changed, 199 insertions(+) create mode 100644 tools/perf/util/config.h diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 664490b..dad7d82 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -13,6 +13,7 @@ #include #include "util/hist.h" /* perf_hist_config */ #include "util/llvm-utils.h" /* perf_llvm_config */ +#include "config.h" #define MAXNAME (256) @@ -524,6 +525,178 @@ out: return ret; } +static struct perf_config_section *find_section(struct list_head *sections, + const char *section_name) +{ + struct perf_config_section *section; + + list_for_each_entry(section, sections, node) + if (!strcmp(section->name, section_name)) + return section; + + return NULL; +} + +static struct perf_config_item *find_config_item(const char *name, +struct perf_config_section *section) +{ + struct perf_config_item *item; + + list_for_each_entry(item, §ion->items, node) + if (!strcmp(item->name, name)) + return item; + + return NULL; +} + +static struct perf_config_section *add_section(struct list_head *sections, + const char *section_name) +{ + struct perf_config_section *section = zalloc(sizeof(*section)); + + if (!section) + return NULL; + + INIT_LIST_HEAD(§ion->items); + section->name = strdup(section_name); + if (!section->name) { + pr_debug("%s: strdup failed\n", __func__); + free(section); + return NULL; + } + + list_add_tail(§ion->node, sections); + return section; +} + +static struct perf_config_item *add_config_item(struct perf_config_section *section, + const char *name) +{ + struct perf_config_item *item = zalloc(sizeof(*item)); + + if (!item) + return NULL; + + item->name = strdup(name); + if (!item->name) { + pr_debug("%s: strdup failed\n", __func__); + free(item); + return NULL; + } + + list_add_tail(&item->node, §ion->items); + return item; +} + +static int set_value(struct perf_config_item *item, const char *value) +{ + char *val = strdup(value); + + if (!val) + return -1; + + zfree(&item->value); + item->value = val; + return 0; +} + +static int collect_config(const char *var, const char *value, + void *perf_config_set) +{ + int ret = -1; + char *ptr, *key; + char *section_name, *name; + struct perf_config_section *section = NULL; + struct perf_config_item *item = NULL; + struct perf_config_set *set = perf_config_set; + struct list_head *sections = &set->sections; + + key = ptr = strdup(var); + if (!key) { + pr_debug("%s: strdup failed\n", __func__); + return -1; + } + + section_name = strsep(&ptr, "."); + name = ptr; + if (name == NULL || value == NULL) + goto out_free; + + section = find_section(sections, section_name); + if (!section) { + section = add_section(sections, section_name); + if (!section) + goto out_free; + } + + item = find_config_item(name, section); + if (!item) { + item = add_config_item(section, name); + if (!item) + goto out_free; + } + + ret = set_value(item, value); + return ret; + +out_free: + free(key); + perf_config_set__delete(set); + return -1; +} + +struct perf_config_set *perf_config_set__new(void) +{ + struct perf_config_set *set = zalloc(sizeof(*set)); + + if (set) { + INIT_LIST_HEAD(&set->sections); + perf_config(collect_config, set); + } + + return set; +} + +static void perf_config_item__delete(struct perf_config_item *item) +{ + zfree(&item->name); + zfree(&item->value); + free(item); +} + +static void perf_config_section__purge(struct perf_config_section *section) +{
[PATCH v8 4/4] perf config: Initialize perf_config_set with all default configs
To avoid duplicated config variables and use perf_config_set classifying between standard perf config variables and unknown or new config variables other than them, initialize perf_config_set with all default configs. And this will be needed when showing all configs with default value or checking correct type of a config variable in the near future. Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/builtin-config.c | 11 +++ tools/perf/util/config.c| 39 ++- tools/perf/util/config.h| 7 +++ 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index fe1b77f..0fe9bc5 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -35,6 +35,7 @@ static struct option config_options[] = { static int show_config(struct perf_config_set *set) { + bool has_value = false; struct perf_config_section *section; struct perf_config_item *item; struct list_head *sections; @@ -43,19 +44,21 @@ static int show_config(struct perf_config_set *set) return -1; sections = &set->sections; - if (list_empty(sections)) - return -1; - list_for_each_entry(section, sections, node) { list_for_each_entry(item, §ion->items, node) { char *value = item->value; - if (value) + if (value) { printf("%s.%s=%s\n", section->name, item->name, value); + has_value = true; + } } } + if (!has_value) + return -1; + return 0; } diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 5604392..61af657 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -663,6 +663,7 @@ static struct perf_config_section *add_section(struct list_head *sections, if (!section) return NULL; + section->is_allocated = true; INIT_LIST_HEAD(§ion->items); section->name = strdup(section_name); if (!section->name) { @@ -683,6 +684,7 @@ static struct perf_config_item *add_config_item(struct perf_config_section *sect if (!item) return NULL; + item->is_allocated = true; item->name = strdup(name); if (!item->name) { pr_debug("%s: strdup failed\n", __func__); @@ -751,12 +753,35 @@ out_free: return -1; } +static struct perf_config_set *perf_config_set__init(struct perf_config_set *set) +{ + int i, j; + struct perf_config_section *section; + struct perf_config_item *items; + struct list_head *sections = &set->sections; + + INIT_LIST_HEAD(&set->sections); + + for (i = 0; i != CONFIG_END; i++) { + section = &default_sections[i]; + INIT_LIST_HEAD(§ion->items); + + items = default_config_items[i]; + for (j = 0; items[j].name != NULL; j++) + list_add_tail(&items[j].node, §ion->items); + + list_add_tail(§ion->node, sections); + } + + return set; +} + struct perf_config_set *perf_config_set__new(void) { struct perf_config_set *set = zalloc(sizeof(*set)); if (set) { - INIT_LIST_HEAD(&set->sections); + perf_config_set__init(set); perf_config(collect_config, set); } @@ -765,9 +790,11 @@ struct perf_config_set *perf_config_set__new(void) static void perf_config_item__delete(struct perf_config_item *item) { - zfree((char **)&item->name); zfree(&item->value); - free(item); + if (item->is_allocated) { + zfree((char **)&item->name); + free(item); + } } static void perf_config_section__purge(struct perf_config_section *section) @@ -783,8 +810,10 @@ static void perf_config_section__purge(struct perf_config_section *section) static void perf_config_section__delete(struct perf_config_section *section) { perf_config_section__purge(section); - zfree((char **)§ion->name); - free(section); + if (section->is_allocated) { + zfree((char **)§ion->name); + free(section); + } } static void perf_config_set__purge(struct perf_config_set *set) diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index 84dcc1d..35c0075 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -14,6 +14,11 @@ enum perf_config_type { CONFIG_TYPE_STRING }; +/** + * struct perf_config_item - element of perf's configs + * + * @is_
[PATCH v8 2/4] perf config: Let show_config() work with perf_config_set
Current show_config() has a problem when user or system config files have same config variables i.e. # cat ~/.perfconfig [top] children = false when $(sysconfdir) is /usr/local/etc # cat /usr/local/etc/perfconfig [top] children = true Before: # perf config --user --list top.children=false # perf config --system --list top.children=true # perf config --list top.children=true top.children=false Because perf_config() can call show_config() each the config file (user and system). So fix it. After: # perf config --user --list top.children=false # perf config --system --list top.children=true # perf config --list top.children=false Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/builtin-config.c | 39 --- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index c42448e..fe1b77f 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -12,6 +12,7 @@ #include #include "util/util.h" #include "util/debug.h" +#include "util/config.h" static bool use_system_config, use_user_config; @@ -32,13 +33,28 @@ static struct option config_options[] = { OPT_END() }; -static int show_config(const char *key, const char *value, - void *cb __maybe_unused) +static int show_config(struct perf_config_set *set) { - if (value) - printf("%s=%s\n", key, value); - else - printf("%s\n", key); + struct perf_config_section *section; + struct perf_config_item *item; + struct list_head *sections; + + if (set == NULL) + return -1; + + sections = &set->sections; + if (list_empty(sections)) + return -1; + + list_for_each_entry(section, sections, node) { + list_for_each_entry(item, §ion->items, node) { + char *value = item->value; + + if (value) + printf("%s.%s=%s\n", section->name, + item->name, value); + } + } return 0; } @@ -46,6 +62,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 perf_config_set *set; char *user_config = mkpath("%s/.perfconfig", getenv("HOME")); argc = parse_options(argc, argv, config_options, config_usage, @@ -63,13 +80,19 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) else if (use_user_config) config_exclusive_filename = user_config; + set = perf_config_set__new(); + if (!set) { + ret = -1; + goto out_err; + } + 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(set); if (ret < 0) { const char * config_filename = config_exclusive_filename; if (!config_exclusive_filename) @@ -83,5 +106,7 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) usage_with_options(config_usage, config_options); } + perf_config_set__delete(set); +out_err: return ret; } -- 2.5.0
[RFC][PATCH v8 0/4] Infrastructure code for perf-config
Hi, We can use the config files (i.e user wide ~/.perfconfig and system wide $(sysconfdir)/perfconfig) to configure perf tools. perf-config help user manage the config files, not manually look into or edit them. Introduce new infrastructure code for config management features of perf-config subcommand. This pathset contains basic code for various purposes of configuration management showing current configs, in the near future, showing all configs with default value, getting current configs from the config files or writing configs that user type on the config files, etc. IMHO, I think this infrastructure code is needed to add new funcationalities for config management of perf-config. If anyone reviews this, I'd appreciate it. Thanks, Taeung v8: - rebased onto the current acme/perf/core v7: - rename 'is_custom' to 'is_allocated' to be proper (Masami) - fix the code about free() or zfree() in perf_config_*__delete() (Masami) - check set == NULL or not in show_config() (Masami) v6: - don't use goto in add_config_item() (Masami) v5: - departmentalize perf_config_set__delete() (Arnaldo) - remove confusing find_config() (Arnaldo) - use pr_debug() instead of pr_err() (Arnaldo) - use zfree() instead of free() (Arnaldo) - more compact in perf_config_set__new() (Arnaldo) - rename variables 'perf_configs', 'config_items', etc. (Arnaldo) v4: - fill perf_config_set__delete() in collect_config() for state of error - fill the code setting is_custom value in add_config_item() (Namhyung) v3: - use the section list that contains configs each section instead of the single config list (Namhyung) - exclude a patch for '--list-all' option from this patchset v2: - remove perf_config_kind (user, system or both config files) and needless at this time, etc. (Namhyung) - separate this patch as several patches (Namhyung) - fix typing errors, etc. Taeung Song (4): perf config: Introduce perf_config_set class perf config: Let show_config() work with perf_config_set perf config: Prepare all default configs perf config: Initialize perf_config_set with all default configs tools/perf/builtin-config.c | 42 +- tools/perf/util/config.c| 308 tools/perf/util/config.h| 91 + 3 files changed, 434 insertions(+), 7 deletions(-) create mode 100644 tools/perf/util/config.h -- 2.5.0
[PATCH v8 3/4] perf config: Prepare all default configs
To precisely manage configs, prepare all default perf's configs that contain default section name, variable name, value and correct type, not string type. In the near future, this will be used when checking type of config variable or showing all configs with default values, etc. Acked-by: Namhyung Kim Cc: Masami Hiramatsu Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/util/config.c | 110 ++- tools/perf/util/config.h | 62 +- 2 files changed, 168 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index dad7d82..5604392 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -15,6 +15,7 @@ #include "util/llvm-utils.h" /* perf_llvm_config */ #include "config.h" +#define MAX_CONFIGS 64 #define MAXNAME (256) #define DEBUG_CACHE_DIR ".debug" @@ -29,6 +30,111 @@ static int config_file_eof; const char *config_exclusive_filename; +struct perf_config_section default_sections[] = { + { .name = "colors" }, + { .name = "tui" }, + { .name = "buildid" }, + { .name = "annotate" }, + { .name = "gtk" }, + { .name = "pager" }, + { .name = "help" }, + { .name = "hist" }, + { .name = "ui" }, + { .name = "call-graph" }, + { .name = "report" }, + { .name = "top" }, + { .name = "man" }, + { .name = "kmem" } +}; + +struct perf_config_item default_config_items[][MAX_CONFIGS] = { + [CONFIG_COLORS] = { + CONF_STR_VAR("top", "red, default"), + CONF_STR_VAR("medium", "green, default"), + CONF_STR_VAR("normal", "lightgray, default"), + CONF_STR_VAR("selected", "white, lightgray"), + CONF_STR_VAR("jump_arrows", "blue, default"), + CONF_STR_VAR("addr", "magenta, default"), + CONF_STR_VAR("root", "white, blue"), + CONF_END() + }, + [CONFIG_TUI] = { + CONF_BOOL_VAR("report", true), + CONF_BOOL_VAR("annotate", true), + CONF_BOOL_VAR("top", true), + CONF_END() + }, + [CONFIG_BUILDID] = { + CONF_STR_VAR("dir", "~/.debug"), + CONF_END() + }, + [CONFIG_ANNOTATE] = { + CONF_BOOL_VAR("hide_src_code", false), + CONF_BOOL_VAR("use_offset", true), + CONF_BOOL_VAR("jump_arrows", true), + CONF_BOOL_VAR("show_nr_jumps", false), + CONF_BOOL_VAR("show_linenr", false), + CONF_BOOL_VAR("show_total_period", false), + CONF_END() + }, + [CONFIG_GTK] = { + CONF_BOOL_VAR("annotate", false), + CONF_BOOL_VAR("report", false), + CONF_BOOL_VAR("top", false), + CONF_END() + }, + [CONFIG_PAGER] = { + CONF_BOOL_VAR("cmd", true), + CONF_BOOL_VAR("report", true), + CONF_BOOL_VAR("annotate", true), + CONF_BOOL_VAR("top", true), + CONF_BOOL_VAR("diff", true), + CONF_END() + }, + [CONFIG_HELP] = { + CONF_STR_VAR("format", "man"), + CONF_INT_VAR("autocorrect", 0), + CONF_END() + }, + [CONFIG_HIST] = { + CONF_STR_VAR("percentage", "absolute"), + CONF_END() + }, + [CONFIG_UI] = { + CONF_BOOL_VAR("show-headers", true), + CONF_END() + }, + [CONFIG_CALL_GRAPH] = { + CONF_STR_VAR("record-mode", "fp"), + CONF_LONG_VAR("dump-size", 8192), + CONF_STR_VAR("print-type", "graph"), + CONF_STR_VAR("order", "callee"), + CONF_STR_VAR("sort-key", "function"), + CONF_DOUBLE_VAR("threshold", 0.5), + CONF_LONG_VAR("print-limit", 0), + CONF_END() + }, + [CONFIG_REPORT] = { + CONF_BOOL_VAR("group", true), + CONF_BOOL_VAR("children", true), + CONF_FLOAT_VAR("percent-limit", 0), + CONF_U64_VAR("queue-size", 0), + CONF_END() +
Re: [PATCH v8 3/4] perf config: Prepare all default configs
Hi, Arnaldo On 04/14/2016 09:19 PM, Arnaldo Carvalho de Melo wrote: Em Thu, Apr 14, 2016 at 04:53:20PM +0900, Taeung Song escreveu: To precisely manage configs, prepare all default perf's configs that contain default section name, variable name, value and correct type, not string type. In the near future, this will be used when checking type of config variable or showing all configs with default values, etc. Acked-by: Namhyung Kim Cc: Masami Hiramatsu Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/util/config.c | 110 ++- tools/perf/util/config.h | 62 +- 2 files changed, 168 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index dad7d82..5604392 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -15,6 +15,7 @@ #include "util/llvm-utils.h" /* perf_llvm_config */ #include "config.h" +#define MAX_CONFIGS 64 Do we have to add another arbitrary maximum? Where is it used? IMHO, it is my idea. If you want to avoid using this arbitrary maxinum, I'd modify the code. MAX_CONFIGS is used in order to declare two-dimensional arrays 'default_config_items' as below. struct perf_config_item default_config_items[][MAX_CONFIGS] = { [CONFIG_COLORS] = { CONF_STR_VAR("top", "red, default"), CONF_STR_VAR("medium", "green, default"), ...(omitted)... IMHO, it is because of perf_config_set__init() in [PATCH v8 4/4]. If we don't use two-dimensional arrays, I think the code of perf_config_set__init() could be complicated. Thanks, Taeung #define MAXNAME (256) #define DEBUG_CACHE_DIR ".debug" @@ -29,6 +30,111 @@ static int config_file_eof; const char *config_exclusive_filename; +struct perf_config_section default_sections[] = { + { .name = "colors" }, + { .name = "tui" }, + { .name = "buildid" }, + { .name = "annotate" }, + { .name = "gtk" }, + { .name = "pager" }, + { .name = "help" }, + { .name = "hist" }, + { .name = "ui" }, + { .name = "call-graph" }, + { .name = "report" }, + { .name = "top" }, + { .name = "man" }, + { .name = "kmem" } +}; + +struct perf_config_item default_config_items[][MAX_CONFIGS] = { + [CONFIG_COLORS] = { + CONF_STR_VAR("top", "red, default"), + CONF_STR_VAR("medium", "green, default"), + CONF_STR_VAR("normal", "lightgray, default"), + CONF_STR_VAR("selected", "white, lightgray"), + CONF_STR_VAR("jump_arrows", "blue, default"), + CONF_STR_VAR("addr", "magenta, default"), + CONF_STR_VAR("root", "white, blue"), + CONF_END() + }, + [CONFIG_TUI] = { + CONF_BOOL_VAR("report", true), + CONF_BOOL_VAR("annotate", true), + CONF_BOOL_VAR("top", true), + CONF_END() + }, + [CONFIG_BUILDID] = { + CONF_STR_VAR("dir", "~/.debug"), + CONF_END() + }, + [CONFIG_ANNOTATE] = { + CONF_BOOL_VAR("hide_src_code", false), + CONF_BOOL_VAR("use_offset", true), + CONF_BOOL_VAR("jump_arrows", true), + CONF_BOOL_VAR("show_nr_jumps", false), + CONF_BOOL_VAR("show_linenr", false), + CONF_BOOL_VAR("show_total_period", false), + CONF_END() + }, + [CONFIG_GTK] = { + CONF_BOOL_VAR("annotate", false), + CONF_BOOL_VAR("report", false), + CONF_BOOL_VAR("top", false), + CONF_END() + }, + [CONFIG_PAGER] = { + CONF_BOOL_VAR("cmd", true), + CONF_BOOL_VAR("report", true), + CONF_BOOL_VAR("annotate", true), + CONF_BOOL_VAR("top", true), + CONF_BOOL_VAR("diff", true), + CONF_END() + }, + [CONFIG_HELP] = { + CONF_STR_VAR("format", "man"), + CONF_INT_VAR("autocorrect", 0), + CONF_END() + }, + [CONFIG_HIST] = { + CONF_STR_VAR("percentage", "absolute"), + CONF_END() + }, + [CONFIG_UI] = { + CONF_BOOL_VAR("show-headers",
[PATCH 0/4] perf config: Introduce default config key-value pairs arrays
We currently use values of actual type(int, bool, char *, etc.) when initializing default perf config values. For example, If there isn't user config value at ~/.perfconfig for 'annotate.use_offset' config variable, default value for it is 'true' bool type value in perf like below. At ui/browsers/annoate.c static struct annotate_browser_opt { bool hide_src_code, use_offset, jump_arrows, show_linenr, show_nr_jumps, show_total_period; } annotate_browser__opts = { .use_offset = true, .jump_arrows = true, }; But I suggest using new config arrays that have all default config key-value pairs and then initializing default config values with them. Because if we do, we can manage default perf config values at one spot (like util/config.c) and It can be easy and simple to modify default config values or add new configs. For example, If we use new default config arrays and there isn't user config value for 'annoate.use_offset' default value for it will be set as annotate_config_items[CONFIG_ANNOATE_USE_OFFSET].value instead of actual boolean type value 'true'. IMHO, I think it should be needed to use new default config arrays to manage default perf config values more effectively. And this pathset contains patchs for only 'colors' and 'annoate' section because waiting for other opinions. If you review this patchset, I'd appreciate it :-) Thanks, Taeung Taeung Song (4): perf config: Introduce default_config_item for all default config key-value pairs perf tools: Separate out code setting ground colors from ui_browser__color_config perf config: Initialize ui_browser__colorsets with default config items perf config: Initialize annotate_browser__opts with default config items tools/perf/ui/browser.c | 89 ++ tools/perf/ui/browser.h | 1 + tools/perf/ui/browsers/annotate.c | 12 ++- tools/perf/ui/tui/setup.c | 1 + tools/perf/util/cache.h | 1 + tools/perf/util/config.c | 150 +- tools/perf/util/config.h | 74 ++- 7 files changed, 291 insertions(+), 37 deletions(-) -- 2.5.0
[PATCH 1/4] perf config: Introduce default_config_item for all default config key-value pairs
We currently use values of actual type(int, bool, char *, etc.) when initializing default perf config values. But I suggest using new config arrays(default_config_items) that have all default perf config key-value pairs. Because if we do, we can manage default perf config values at one spot (like util/config.c) and it can be easy and simple to modify default config values or add new configs. In the near future, this could be used when showing all configs with default values, initializing default values of each actual config variable with the default_config_item arrays and etc. Cc: Namhyung Kim Cc: Masami Hiramatsu Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/util/config.c | 150 ++- tools/perf/util/config.h | 46 ++- 2 files changed, 194 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index dad7d82..3a72ed7 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -29,6 +29,154 @@ static int config_file_eof; const char *config_exclusive_filename; +const struct perf_config_section default_sections[] = { + { .name = "colors" }, + { .name = "tui" }, + { .name = "buildid" }, + { .name = "annotate" }, + { .name = "gtk" }, + { .name = "pager" }, + { .name = "help" }, + { .name = "hist" }, + { .name = "ui" }, + { .name = "call-graph" }, + { .name = "report" }, + { .name = "top" }, + { .name = "man" }, + { .name = "kmem" }, + { .name = "intel-pt" }, + { .name = "convert" }, +}; + +const struct default_config_item colors_config_items[] = { + CONF_STR_VAR("top", "red, default"), + CONF_STR_VAR("medium", "green, default"), + CONF_STR_VAR("normal", "default, default"), + CONF_STR_VAR("selected", "black, yellow"), + CONF_STR_VAR("jump_arrows", "blue, default"), + CONF_STR_VAR("addr", "magenta, default"), + CONF_STR_VAR("root", "white, blue"), + CONF_END() +}; + +const struct default_config_item tui_config_items[] = { + CONF_BOOL_VAR("report", true), + CONF_BOOL_VAR("annotate", true), + CONF_BOOL_VAR("top", true), + CONF_END() +}; + +const struct default_config_item buildid_config_items[] = { + CONF_STR_VAR("dir", "~/.debug"), + CONF_END() +}; + +const struct default_config_item annotate_config_items[] = { + CONF_BOOL_VAR("hide_src_code", false), + CONF_BOOL_VAR("use_offset", true), + CONF_BOOL_VAR("jump_arrows", true), + CONF_BOOL_VAR("show_nr_jumps", false), + CONF_BOOL_VAR("show_linenr", false), + CONF_BOOL_VAR("show_total_period", false), + CONF_END() +}; + +const struct default_config_item gtk_config_items[] = { + CONF_BOOL_VAR("annotate", false), + CONF_BOOL_VAR("report", false), + CONF_BOOL_VAR("top", false), + CONF_END() +}; + +const struct default_config_item pager_config_items[] = { + CONF_BOOL_VAR("cmd", true), + CONF_BOOL_VAR("report", true), + CONF_BOOL_VAR("annotate", true), + CONF_BOOL_VAR("top", true), + CONF_BOOL_VAR("diff", true), + CONF_END() +}; + +const struct default_config_item help_config_items[] = { + CONF_STR_VAR("format", "man"), + CONF_INT_VAR("autocorrect", 0), + CONF_END() +}; + +const struct default_config_item hist_config_items[] = { + CONF_STR_VAR("percentage", "absolute"), + CONF_END() +}; + +const struct default_config_item ui_config_items[] = { + CONF_BOOL_VAR("show-headers", true), + CONF_END() +}; + +const struct default_config_item call_graph_config_items[] = { + CONF_STR_VAR("record-mode", "fp"), + CONF_LONG_VAR("dump-size", 8192), + CONF_STR_VAR("print-type", "graph"), + CONF_STR_VAR("order", "callee"), + CONF_STR_VAR("sort-key", "function"), + CONF_DOUBLE_VAR("threshold", 0.5), + CONF_LONG_VAR("print-limit", 0), + CONF_END() +}; + +const struct default_config_item report_config_items[] = { + CONF_BOOL_VAR("group", true), + CONF_BOOL_VAR("children", true), + CONF_FLOAT_VAR("percent-limit", 0), + CONF_U64_VAR("queue-size", 0), + CONF_END() +}; + +
[PATCH 3/4] perf config: Initialize ui_browser__colorsets with default config items
Set default config values for 'colors' section with 'colors_config_items[]' instead of actual const char * type values. (e.g. using colors_config_item[CONFIG_COLORS_TOP].value instead of "red, default" string value for 'colors.top') Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browser.c | 46 -- tools/perf/ui/browser.h | 1 + tools/perf/ui/tui/setup.c | 1 + tools/perf/util/cache.h | 1 + tools/perf/util/config.h | 12 5 files changed, 47 insertions(+), 14 deletions(-) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index a477867..385d0de 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -509,44 +509,30 @@ static struct ui_browser_colorset { { .colorset = HE_COLORSET_TOP, .name = "top", - .fg = "red", - .bg = "default", }, { .colorset = HE_COLORSET_MEDIUM, .name = "medium", - .fg = "green", - .bg = "default", }, { .colorset = HE_COLORSET_NORMAL, .name = "normal", - .fg = "default", - .bg = "default", }, { .colorset = HE_COLORSET_SELECTED, .name = "selected", - .fg = "black", - .bg = "yellow", }, { .colorset = HE_COLORSET_JUMP_ARROWS, .name = "jump_arrows", - .fg = "blue", - .bg = "default", }, { .colorset = HE_COLORSET_ADDR, .name = "addr", - .fg = "magenta", - .bg = "default", }, { .colorset = HE_COLORSET_ROOT, .name = "root", - .fg = "white", - .bg = "blue", }, { .name = NULL, @@ -591,6 +577,7 @@ static int ui_browser__color_config(const char *var, const char *value, if (strcmp(ui_browser__colorsets[i].name, name) != 0) continue; + zfree((char **)&ui_browser__colorsets[i].fg); ret = ui_browser__config_gcolors(&ui_browser__colorsets[i], value); break; } @@ -745,10 +732,41 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, __ui_browser__line_arrow_down(browser, column, start, end); } +static void ui_browser__free_color_configs(void) +{ + int i; + + for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) + zfree((char **)&ui_browser__colorsets[i].fg); +} + +void ui_browser__free(void) +{ + ui_browser__free_color_configs(); +} + +static void ui_browser__init_colorsets(void) +{ + int i, j; + + for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) { + const char *name = ui_browser__colorsets[i].name; + + for (j = 0; colors_config_items[j].name != NULL; j++) { + if (!strcmp(name, colors_config_items[j].name)) { + ui_browser__config_gcolors(&ui_browser__colorsets[i], + colors_config_items[j].value.s); + break; + } + } + } +} + void ui_browser__init(void) { int i = 0; + ui_browser__init_colorsets(); perf_config(ui_browser__color_config, NULL); while (ui_browser__colorsets[i].name) { diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index be3b70e..7a83a1a 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h @@ -74,5 +74,6 @@ void ui_browser__list_head_seek(struct ui_browser *browser, off_t offset, int wh unsigned int ui_browser__list_head_refresh(struct ui_browser *browser); void ui_browser__init(void); +void ui_browser__free(void); void annotate_browser__init(void); #endif /* _PERF_UI_BROWSER_H_ */ diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index 7dfeba0..7999a57 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -171,4 +171,5 @@ void ui__exit(bool wait_for_ok) SLang_reset_tty(); perf_error__unregister(&perf_tui_eops); + ui_browser__free(); } diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 1f5a93c..8eab653 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -7,6 +7,7 @@ #in
[PATCH 2/4] perf tools: Separate out code setting ground colors from ui_browser__color_config
ui_browser__color_config() set foreground and background colors values in ui_browser__colorsets. But it can be reused by other functions so make ui_browser__config_gcolors() bringing it from ui_browser__color_config(). Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browser.c | 43 ++- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index af68a9d..a477867 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -553,12 +553,33 @@ static struct ui_browser_colorset { } }; +static int ui_browser__config_gcolors(struct ui_browser_colorset *ui_browser_color, + const char *value) +{ + char *fg = NULL, *bg; + + fg = strdup(value); + if (fg == NULL) + return -1; + + bg = strchr(fg, ','); + if (bg == NULL) { + free(fg); + return -1; + } + + *bg = '\0'; + while (isspace(*++bg)); + + ui_browser_color->fg = fg; + ui_browser_color->bg = bg; + return 0; +} static int ui_browser__color_config(const char *var, const char *value, void *data __maybe_unused) { - char *fg = NULL, *bg; - int i; + int i, ret; /* same dir for all commands */ if (prefixcmp(var, "colors.") != 0) @@ -570,23 +591,11 @@ static int ui_browser__color_config(const char *var, const char *value, if (strcmp(ui_browser__colorsets[i].name, name) != 0) continue; - fg = strdup(value); - if (fg == NULL) - break; - - bg = strchr(fg, ','); - if (bg == NULL) - break; - - *bg = '\0'; - while (isspace(*++bg)); - ui_browser__colorsets[i].bg = bg; - ui_browser__colorsets[i].fg = fg; - return 0; + ret = ui_browser__config_gcolors(&ui_browser__colorsets[i], value); + break; } - free(fg); - return -1; + return ret; } void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence) -- 2.5.0
[PATCH 4/4] perf config: Initialize annotate_browser__opts with default config items
Set default config values for 'annotate' section with 'annotate_config_items[]' instead of actual bool type values. (e.g. using annotate_config_items[CONFIG_ANNOTATE_USE_OFFSET].value instead of 'true' bool type value for 'annotate.use_offset'.) Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browsers/annotate.c | 12 tools/perf/util/config.h | 16 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 4fc208e..f52e1ea 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -37,10 +37,7 @@ static struct annotate_browser_opt { show_linenr, show_nr_jumps, show_total_period; -} annotate_browser__opts = { - .use_offset = true, - .jump_arrows= true, -}; +} annotate_browser__opts; struct annotate_browser { struct ui_browser b; @@ -1160,5 +1157,12 @@ static int annotate__config(const char *var, const char *value, void annotate_browser__init(void) { + annotate_browser__opts.hide_src_code = CONF_ANNOTATE_DEFAULT_VAL(HIDE_SRC_CODE, b); + annotate_browser__opts.use_offset = CONF_ANNOTATE_DEFAULT_VAL(USE_OFFSET, b); + annotate_browser__opts.jump_arrows = CONF_ANNOTATE_DEFAULT_VAL(JUMP_ARROWS, b); + annotate_browser__opts.show_linenr = CONF_ANNOTATE_DEFAULT_VAL(SHOW_LINENR, b); + annotate_browser__opts.show_nr_jumps = CONF_ANNOTATE_DEFAULT_VAL(SHOW_NR_JUMPS, b); + annotate_browser__opts.show_total_period = CONF_ANNOTATE_DEFAULT_VAL(SHOW_TOTAL_PERIOD, b); + perf_config(annotate__config, NULL); } diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index e0c8392..344b344 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -54,6 +54,15 @@ enum colors_config_items_idx { CONFIG_COLORS_ROOT, }; +enum annotate_config_items_idx { + 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, +}; + #define CONF_VAR(_name, _field, _val, _type) \ { .name = _name, .value._field = _val, .type = _type } @@ -74,7 +83,14 @@ enum colors_config_items_idx { #define CONF_END() \ { .name = NULL } +#define CONF_DEFAULT_VAL(section, name, field) \ + section##_config_items[CONFIG_##name].value.field + +#define CONF_ANNOTATE_DEFAULT_VAL(name, field) \ + CONF_DEFAULT_VAL(annotate, ANNOTATE_##name, field) + extern const struct default_config_item colors_config_items[]; +extern const struct default_config_item annotate_config_items[]; struct perf_config_set *perf_config_set__new(void); void perf_config_set__delete(struct perf_config_set *set); -- 2.5.0
[PATCH v11 1/1] perf config: Prepare all default configs
To precisely manage configs, prepare all default perf's configs that contain default section name, variable name, value and correct type, not string type. In the near future, this could be used when showing all configs with default values, replacing default values of each actual config variable with the default_config_item arrays and etc. Cc: Namhyung Kim Cc: Masami Hiramatsu Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/util/config.c | 150 ++- tools/perf/util/config.h | 46 ++- 2 files changed, 194 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index dad7d82..3a72ed7 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -29,6 +29,154 @@ static int config_file_eof; const char *config_exclusive_filename; +const struct perf_config_section default_sections[] = { + { .name = "colors" }, + { .name = "tui" }, + { .name = "buildid" }, + { .name = "annotate" }, + { .name = "gtk" }, + { .name = "pager" }, + { .name = "help" }, + { .name = "hist" }, + { .name = "ui" }, + { .name = "call-graph" }, + { .name = "report" }, + { .name = "top" }, + { .name = "man" }, + { .name = "kmem" }, + { .name = "intel-pt" }, + { .name = "convert" }, +}; + +const struct default_config_item colors_config_items[] = { + CONF_STR_VAR("top", "red, default"), + CONF_STR_VAR("medium", "green, default"), + CONF_STR_VAR("normal", "default, default"), + CONF_STR_VAR("selected", "black, yellow"), + CONF_STR_VAR("jump_arrows", "blue, default"), + CONF_STR_VAR("addr", "magenta, default"), + CONF_STR_VAR("root", "white, blue"), + CONF_END() +}; + +const struct default_config_item tui_config_items[] = { + CONF_BOOL_VAR("report", true), + CONF_BOOL_VAR("annotate", true), + CONF_BOOL_VAR("top", true), + CONF_END() +}; + +const struct default_config_item buildid_config_items[] = { + CONF_STR_VAR("dir", "~/.debug"), + CONF_END() +}; + +const struct default_config_item annotate_config_items[] = { + CONF_BOOL_VAR("hide_src_code", false), + CONF_BOOL_VAR("use_offset", true), + CONF_BOOL_VAR("jump_arrows", true), + CONF_BOOL_VAR("show_nr_jumps", false), + CONF_BOOL_VAR("show_linenr", false), + CONF_BOOL_VAR("show_total_period", false), + CONF_END() +}; + +const struct default_config_item gtk_config_items[] = { + CONF_BOOL_VAR("annotate", false), + CONF_BOOL_VAR("report", false), + CONF_BOOL_VAR("top", false), + CONF_END() +}; + +const struct default_config_item pager_config_items[] = { + CONF_BOOL_VAR("cmd", true), + CONF_BOOL_VAR("report", true), + CONF_BOOL_VAR("annotate", true), + CONF_BOOL_VAR("top", true), + CONF_BOOL_VAR("diff", true), + CONF_END() +}; + +const struct default_config_item help_config_items[] = { + CONF_STR_VAR("format", "man"), + CONF_INT_VAR("autocorrect", 0), + CONF_END() +}; + +const struct default_config_item hist_config_items[] = { + CONF_STR_VAR("percentage", "absolute"), + CONF_END() +}; + +const struct default_config_item ui_config_items[] = { + CONF_BOOL_VAR("show-headers", true), + CONF_END() +}; + +const struct default_config_item call_graph_config_items[] = { + CONF_STR_VAR("record-mode", "fp"), + CONF_LONG_VAR("dump-size", 8192), + CONF_STR_VAR("print-type", "graph"), + CONF_STR_VAR("order", "callee"), + CONF_STR_VAR("sort-key", "function"), + CONF_DOUBLE_VAR("threshold", 0.5), + CONF_LONG_VAR("print-limit", 0), + CONF_END() +}; + +const struct default_config_item report_config_items[] = { + CONF_BOOL_VAR("group", true), + CONF_BOOL_VAR("children", true), + CONF_FLOAT_VAR("percent-limit", 0), + CONF_U64_VAR("queue-size", 0), + CONF_END() +}; + +const struct default_config_item top_config_items[] = { + CONF_BOOL_VAR("children", true), + CONF_END() +}; + +const struct default_config_item man_config_items[] = { + CONF_STR_VAR("viewer", "man")
[PATCH v11 0/1] Infrastructure code for perf-config
Hi, We can use the config files (i.e user wide ~/.perfconfig and system wide $(sysconfdir)/perfconfig) to configure perf tools. perf-config help user manage the config files, not manually look into or edit them. Introduce new infrastructure code for config management features of perf-config subcommand. This pathset contains basic code for various purposes of configuration management showing current configs, in the near future, showing all configs with default value, getting current configs from the config files or writing configs that user type on the config files, etc. IMHO, I think this infrastructure code is needed to add new funcationalities for config management of perf-config. If anyone reviews this, I'd appreciate it. Thanks, Taeung v11: - don't initialize perf_config_set with all default configs and remove the patch for it. - add struct default_config_item for only default config (Namhyung) - define each default_config_item array as const type (Namhyung) - In the near future, default values of each actual config variable could be replaced with the default_config_item arrays (Namhyung) v10: - fix default values of colors.normal and colors.selected according ui_browser__colorsets[] at ui/browser.c - recheck all default config values looking into relevant codes - v9 1/2, 2/2 acked by Namhyung Kim (see https://lkml.org/lkml/2016/4/20/834) v9: - don't use the arbitrary maximum 'MAX_CONFIGS' (Arnaldo, Namhyung) - change two-dimensinal arrays 'default_config_items' to array of pointers (Namhyung) - remove needless 'enum perf_config_secion_idx' - add sections 'intel-pt','convert' and their items - modify perf_config_set__init() in accordance with new default config sections and items - (applied two previous patches 860b8d4 and 20105ca from this patchset) v8: - rebased onto the current acme/perf/core v7: - rename 'is_custom' to 'is_allocated' to be proper (Masami) - fix the code about free() or zfree() in perf_config_*__delete() (Masami) - check set == NULL or not in show_config() (Masami) v6: - don't use goto in add_config_item() (Masami) v5: - departmentalize perf_config_set__delete() (Arnaldo) - remove confusing find_config() (Arnaldo) - use pr_debug() instead of pr_err() (Arnaldo) - use zfree() instead of free() (Arnaldo) - more compact in perf_config_set__new() (Arnaldo) - rename variables 'perf_configs', 'config_items', etc. (Arnaldo) v4: - fill perf_config_set__delete() in collect_config() for state of error - fill the code setting is_custom value in add_config_item() (Namhyung) v3: - use the section list that contains configs each section instead of the single config list (Namhyung) - exclude a patch for '--list-all' option from this patchset v2: - remove perf_config_kind (user, system or both config files) and needless at this time, etc. (Namhyung) - separate this patch as several patches (Namhyung) - fix typing errors, etc. Taeung Song (1): perf config: Prepare all default configs tools/perf/util/config.c | 150 ++- tools/perf/util/config.h | 46 ++- 2 files changed, 194 insertions(+), 2 deletions(-) -- 2.5.0
Re: [PATCH 2/4] perf tools: Separate out code setting ground colors from ui_browser__color_config
Hi, Arnaldo :) On 05/10/2016 02:17 AM, Arnaldo Carvalho de Melo wrote: Em Mon, May 09, 2016 at 08:41:47PM +0900, Taeung Song escreveu: ui_browser__color_config() set foreground and background colors values in ui_browser__colorsets. "ground colors" sounds strange, I guess referreing to them as "*colors" or "{back,fore}ground colors" is more appropriate, replace "gcolors" with "colors" too, please. I got it. But it can be reused by other functions so make ui_browser__config_gcolors() bringing it from ui_browser__color_config(). Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browser.c | 43 ++- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index af68a9d..a477867 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -553,12 +553,33 @@ static struct ui_browser_colorset { } }; +static int ui_browser__config_gcolors(struct ui_browser_colorset *ui_browser_color, + const char *value) +{ + char *fg = NULL, *bg; + + fg = strdup(value); + if (fg == NULL) + return -1; + + bg = strchr(fg, ','); + if (bg == NULL) { + free(fg); + return -1; + } + + *bg = '\0'; Isn't the above strtok()? + while (isspace(*++bg)); Isn't this ltrim()? I modified it like below and retested it ! diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index a477867..c905445 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -553,8 +553,8 @@ static struct ui_browser_colorset { } }; -static int ui_browser__config_gcolors(struct ui_browser_colorset *ui_browser_color, - const char *value) +static int ui_browser__config_colors(struct ui_browser_colorset *ui_browser_color, + const char *value) { char *fg = NULL, *bg; @@ -562,14 +562,12 @@ static int ui_browser__config_gcolors(struct ui_browser_colorset *ui_browser_col if (fg == NULL) return -1; -bg = strchr(fg, ','); +bg = strtok(fg, ","); if (bg == NULL) { free(fg); return -1; } - -*bg = '\0'; -while (isspace(*++bg)); +ltrim(bg); ui_browser_color->fg = fg; ui_browser_color->bg = bg; @@ -591,7 +589,7 @@ static int ui_browser__color_config(const char *var, const char *value, if (strcmp(ui_browser__colorsets[i].name, name) != 0) continue; -ret = ui_browser__config_gcolors(&ui_browser__colorsets[i], value); +ret = ui_browser__config_colors(&ui_browser__colorsets[i], value); break; } I'll send this modified patch with v2 Thanks, Taeung
Re: [PATCH 1/4] perf config: Introduce default_config_item for all default config key-value pairs
Hi, Arnaldo, Namhyung and jirka :) On 05/10/2016 02:17 AM, Arnaldo Carvalho de Melo wrote: Em Mon, May 09, 2016 at 08:41:46PM +0900, Taeung Song escreveu: We currently use values of actual type(int, bool, char *, etc.) when initializing default perf config values. But I suggest using new config arrays(default_config_items) that have all default perf config key-value pairs. Because if we do, we can manage default perf config values at one spot (like util/config.c) and it can be easy and simple to modify default config values or add new configs. In the near future, this could be used when showing all configs with default values, initializing default values of each actual config variable with the default_config_item arrays and etc. looks ok Thank you for your review !! :-) We can use this patch as it is, but what about this change ? diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index 84414af..8e143fb 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -5,6 +5,9 @@ #include enum perf_config_type { +/* special type */ +CONFIG_END, + CONFIG_TYPE_BOOL, CONFIG_TYPE_INT, CONFIG_TYPE_LONG, @@ -14,8 +17,10 @@ enum perf_config_type { CONFIG_TYPE_STRING }; +#define MAX_CONFIG_NAME 100 + struct default_config_item { -const char *name; +const char name[MAX_CONFIG_NAME]; union { bool b; int i; @@ -62,7 +67,7 @@ struct perf_config_set { #define CONF_STR_VAR(_name, _val) \ CONF_VAR(_name, s, _val, CONFIG_TYPE_STRING) #define CONF_END() \ -{ .name = NULL } +{ .type = CONFIG_END } Because if we do, we can use name of default_config_item as a constant to replace values of actual type(int, char *, etc) with colors_config_items[].name more easy e.g. (Contrastively if we use 'name' member variable as 'const char *' type, we can't use it as a constant like below. It is a limitation of C language.) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 385d0de..207c62d 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -508,31 +508,31 @@ static struct ui_browser_colorset { } ui_browser__colorsets[] = { { .colorset = HE_COLORSET_TOP, -.name = "top", +.name = colors_config_items[CONFIG_COLORS_TOP].name, }, { .colorset = HE_COLORSET_MEDIUM, -.name = "medium", +.name = colors_config_items[CONFIG_COLORS_MEDIUM].name, }, { .colorset = HE_COLORSET_NORMAL, -.name = "normal", +.name = colors_config_items[CONFIG_COLORS_NORMAL].name, }, { .colorset = HE_COLORSET_SELECTED, -.name = "selected", +.name = colors_config_items[CONFIG_COLORS_SELECTED].name, }, { .colorset = HE_COLORSET_JUMP_ARROWS, -.name = "jump_arrows", +.name = colors_config_items[CONFIG_COLORS_JUMP_ARROWS].name, }, { .colorset = HE_COLORSET_ADDR, -.name = "addr", +.name = colors_config_items[CONFIG_COLORS_ADDR].name, }, { .colorset = HE_COLORSET_ROOT, -.name = "root", +.name = colors_config_items[CONFIG_COLORS_ROOT].name, }, { .name = NULL, If you give me your opinion or other way, I'd appreciate it. :) Thanks, Taeung Cc: Namhyung Kim Cc: Masami Hiramatsu Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/util/config.c | 150 ++- tools/perf/util/config.h | 46 ++- 2 files changed, 194 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index dad7d82..3a72ed7 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -29,6 +29,154 @@ static int config_file_eof; const char *config_exclusive_filename; +const struct perf_config_section default_sections[] = { + { .name = "colors" }, + { .name = "tui" }, + { .name = "buildid" }, + { .name = "annotate" }, + { .name = "gtk" }, + { .name = "pager" }, + { .name = "help" }, + { .name = "hist" }, + { .name = "ui" }, + { .name = "call-graph" }, + { .name = "report" }, + { .name = "top" }, + { .name = "man" }, + { .name = "kmem" }, + { .n
Re: [PATCH 3/4] perf config: Initialize ui_browser__colorsets with default config items
On 05/10/2016 02:19 AM, Arnaldo Carvalho de Melo wrote: Em Mon, May 09, 2016 at 08:41:48PM +0900, Taeung Song escreveu: Set default config values for 'colors' section with 'colors_config_items[]' instead of actual const char * type values. (e.g. using colors_config_item[CONFIG_COLORS_TOP].value instead of "red, default" string value for 'colors.top') looks ok Thank you for your review !! But I'm waiting for your opinion because of previous mail if there's any change, I'll resend this patch after modifying it. :) Thanks, Taeung Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browser.c | 46 -- tools/perf/ui/browser.h | 1 + tools/perf/ui/tui/setup.c | 1 + tools/perf/util/cache.h | 1 + tools/perf/util/config.h | 12 5 files changed, 47 insertions(+), 14 deletions(-) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index a477867..385d0de 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -509,44 +509,30 @@ static struct ui_browser_colorset { { .colorset = HE_COLORSET_TOP, .name = "top", - .fg = "red", - .bg = "default", }, { .colorset = HE_COLORSET_MEDIUM, .name = "medium", - .fg = "green", - .bg = "default", }, { .colorset = HE_COLORSET_NORMAL, .name = "normal", - .fg = "default", - .bg = "default", }, { .colorset = HE_COLORSET_SELECTED, .name = "selected", - .fg = "black", - .bg = "yellow", }, { .colorset = HE_COLORSET_JUMP_ARROWS, .name = "jump_arrows", - .fg = "blue", - .bg = "default", }, { .colorset = HE_COLORSET_ADDR, .name = "addr", - .fg = "magenta", - .bg = "default", }, { .colorset = HE_COLORSET_ROOT, .name = "root", - .fg = "white", - .bg = "blue", }, { .name = NULL, @@ -591,6 +577,7 @@ static int ui_browser__color_config(const char *var, const char *value, if (strcmp(ui_browser__colorsets[i].name, name) != 0) continue; + zfree((char **)&ui_browser__colorsets[i].fg); ret = ui_browser__config_gcolors(&ui_browser__colorsets[i], value); break; } @@ -745,10 +732,41 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, __ui_browser__line_arrow_down(browser, column, start, end); } +static void ui_browser__free_color_configs(void) +{ + int i; + + for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) + zfree((char **)&ui_browser__colorsets[i].fg); +} + +void ui_browser__free(void) +{ + ui_browser__free_color_configs(); +} + +static void ui_browser__init_colorsets(void) +{ + int i, j; + + for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) { + const char *name = ui_browser__colorsets[i].name; + + for (j = 0; colors_config_items[j].name != NULL; j++) { + if (!strcmp(name, colors_config_items[j].name)) { + ui_browser__config_gcolors(&ui_browser__colorsets[i], + colors_config_items[j].value.s); + break; + } + } + } +} + void ui_browser__init(void) { int i = 0; + ui_browser__init_colorsets(); perf_config(ui_browser__color_config, NULL); while (ui_browser__colorsets[i].name) { diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index be3b70e..7a83a1a 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h @@ -74,5 +74,6 @@ void ui_browser__list_head_seek(struct ui_browser *browser, off_t offset, int wh unsigned int ui_browser__list_head_refresh(struct ui_browser *browser); void ui_browser__init(void); +void ui_browser__free(void); void annotate_browser__init(void); #endif /* _PERF_UI_BROWSER_H_ */ diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index 7dfeba0..7999a57 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -171
[PATCH RESEND 2/4] perf tools: Separate out code setting {back, fore}ground colors from ui_browser__color_config
ui_browser__color_config() set foreground and background colors values in ui_browser__colorsets. But it can be reused by other functions so make ui_browser__config_colors() bringing it from ui_browser__color_config(). Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browser.c | 41 - 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index af68a9d..c905445 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -553,12 +553,31 @@ static struct ui_browser_colorset { } }; +static int ui_browser__config_colors(struct ui_browser_colorset *ui_browser_color, +const char *value) +{ + char *fg = NULL, *bg; + + fg = strdup(value); + if (fg == NULL) + return -1; + + bg = strtok(fg, ","); + if (bg == NULL) { + free(fg); + return -1; + } + ltrim(bg); + + ui_browser_color->fg = fg; + ui_browser_color->bg = bg; + return 0; +} static int ui_browser__color_config(const char *var, const char *value, void *data __maybe_unused) { - char *fg = NULL, *bg; - int i; + int i, ret; /* same dir for all commands */ if (prefixcmp(var, "colors.") != 0) @@ -570,23 +589,11 @@ static int ui_browser__color_config(const char *var, const char *value, if (strcmp(ui_browser__colorsets[i].name, name) != 0) continue; - fg = strdup(value); - if (fg == NULL) - break; - - bg = strchr(fg, ','); - if (bg == NULL) - break; - - *bg = '\0'; - while (isspace(*++bg)); - ui_browser__colorsets[i].bg = bg; - ui_browser__colorsets[i].fg = fg; - return 0; + ret = ui_browser__config_colors(&ui_browser__colorsets[i], value); + break; } - free(fg); - return -1; + return ret; } void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence) -- 2.5.0
Re: [PATCH 1/4] perf config: Introduce default_config_item for all default config key-value pairs
Hi, Arnaldo On 05/11/2016 12:05 AM, Arnaldo Carvalho de Melo wrote: Em Tue, May 10, 2016 at 08:49:16PM +0900, Taeung Song escreveu: Hi, Arnaldo, Namhyung and jirka :) On 05/10/2016 02:17 AM, Arnaldo Carvalho de Melo wrote: Em Mon, May 09, 2016 at 08:41:46PM +0900, Taeung Song escreveu: We currently use values of actual type(int, bool, char *, etc.) when initializing default perf config values. But I suggest using new config arrays(default_config_items) that have all default perf config key-value pairs. Because if we do, we can manage default perf config values at one spot (like util/config.c) and it can be easy and simple to modify default config values or add new configs. In the near future, this could be used when showing all configs with default values, initializing default values of each actual config variable with the default_config_item arrays and etc. looks ok Thank you for your review !! :-) We can use this patch as it is, but what about this change ? diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index 84414af..8e143fb 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -5,6 +5,9 @@ #include enum perf_config_type { +/* special type */ +CONFIG_END, + CONFIG_TYPE_BOOL, CONFIG_TYPE_INT, CONFIG_TYPE_LONG, @@ -14,8 +17,10 @@ enum perf_config_type { CONFIG_TYPE_STRING }; +#define MAX_CONFIG_NAME 100 + No hard coded magical maximum values :-\ I got it. I'll send v2 without the above change. :) Thanks, Taeung struct default_config_item { -const char *name; +const char name[MAX_CONFIG_NAME]; union { bool b; int i; @@ -62,7 +67,7 @@ struct perf_config_set { #define CONF_STR_VAR(_name, _val) \ CONF_VAR(_name, s, _val, CONFIG_TYPE_STRING) #define CONF_END() \ -{ .name = NULL } +{ .type = CONFIG_END } Because if we do, we can use name of default_config_item as a constant to replace values of actual type(int, char *, etc) with colors_config_items[].name more easy e.g. (Contrastively if we use 'name' member variable as 'const char *' type, we can't use it as a constant like below. It is a limitation of C language.) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 385d0de..207c62d 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -508,31 +508,31 @@ static struct ui_browser_colorset { } ui_browser__colorsets[] = { { .colorset = HE_COLORSET_TOP, -.name = "top", +.name = colors_config_items[CONFIG_COLORS_TOP].name, }, { .colorset = HE_COLORSET_MEDIUM, -.name = "medium", +.name = colors_config_items[CONFIG_COLORS_MEDIUM].name, }, { .colorset = HE_COLORSET_NORMAL, -.name = "normal", +.name = colors_config_items[CONFIG_COLORS_NORMAL].name, }, { .colorset = HE_COLORSET_SELECTED, -.name = "selected", +.name = colors_config_items[CONFIG_COLORS_SELECTED].name, }, { .colorset = HE_COLORSET_JUMP_ARROWS, -.name = "jump_arrows", +.name = colors_config_items[CONFIG_COLORS_JUMP_ARROWS].name, }, { .colorset = HE_COLORSET_ADDR, -.name = "addr", +.name = colors_config_items[CONFIG_COLORS_ADDR].name, }, { .colorset = HE_COLORSET_ROOT, -.name = "root", +.name = colors_config_items[CONFIG_COLORS_ROOT].name, }, { .name = NULL, If you give me your opinion or other way, I'd appreciate it. :) Thanks, Taeung Cc: Namhyung Kim Cc: Masami Hiramatsu Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/util/config.c | 150 ++- tools/perf/util/config.h | 46 ++- 2 files changed, 194 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index dad7d82..3a72ed7 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -29,6 +29,154 @@ static int config_file_eof; const char *config_exclusive_filename; +const struct perf_config_section default_sections[] = { + { .name = "colors" }, + { .name = "tui" }, + { .name = "buildid" }, + { .name = "annotate" }, + { .name = "gtk" }, + { .name = "pager" }, + { .name = "help&q
[PATCH v2 1/4] perf config: Introduce default_config_item for all default config key-value pairs
We currently use values of actual type(int, bool, char *, etc.) when initializing default perf config values. But I suggest using new config arrays(default_config_items) that have all default perf config key-value pairs. Because if we do, we can manage default perf config values at one spot (like util/config.c) and it can be easy and simple to modify default config values or add new configs. In the near future, this could be used when showing all configs with default values, initializing default values of each actual config variable with the default_config_item arrays and etc. Cc: Namhyung Kim Cc: Masami Hiramatsu Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/util/config.c | 150 ++- tools/perf/util/config.h | 46 ++- 2 files changed, 194 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index dad7d82..3a72ed7 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -29,6 +29,154 @@ static int config_file_eof; const char *config_exclusive_filename; +const struct perf_config_section default_sections[] = { + { .name = "colors" }, + { .name = "tui" }, + { .name = "buildid" }, + { .name = "annotate" }, + { .name = "gtk" }, + { .name = "pager" }, + { .name = "help" }, + { .name = "hist" }, + { .name = "ui" }, + { .name = "call-graph" }, + { .name = "report" }, + { .name = "top" }, + { .name = "man" }, + { .name = "kmem" }, + { .name = "intel-pt" }, + { .name = "convert" }, +}; + +const struct default_config_item colors_config_items[] = { + CONF_STR_VAR("top", "red, default"), + CONF_STR_VAR("medium", "green, default"), + CONF_STR_VAR("normal", "default, default"), + CONF_STR_VAR("selected", "black, yellow"), + CONF_STR_VAR("jump_arrows", "blue, default"), + CONF_STR_VAR("addr", "magenta, default"), + CONF_STR_VAR("root", "white, blue"), + CONF_END() +}; + +const struct default_config_item tui_config_items[] = { + CONF_BOOL_VAR("report", true), + CONF_BOOL_VAR("annotate", true), + CONF_BOOL_VAR("top", true), + CONF_END() +}; + +const struct default_config_item buildid_config_items[] = { + CONF_STR_VAR("dir", "~/.debug"), + CONF_END() +}; + +const struct default_config_item annotate_config_items[] = { + CONF_BOOL_VAR("hide_src_code", false), + CONF_BOOL_VAR("use_offset", true), + CONF_BOOL_VAR("jump_arrows", true), + CONF_BOOL_VAR("show_nr_jumps", false), + CONF_BOOL_VAR("show_linenr", false), + CONF_BOOL_VAR("show_total_period", false), + CONF_END() +}; + +const struct default_config_item gtk_config_items[] = { + CONF_BOOL_VAR("annotate", false), + CONF_BOOL_VAR("report", false), + CONF_BOOL_VAR("top", false), + CONF_END() +}; + +const struct default_config_item pager_config_items[] = { + CONF_BOOL_VAR("cmd", true), + CONF_BOOL_VAR("report", true), + CONF_BOOL_VAR("annotate", true), + CONF_BOOL_VAR("top", true), + CONF_BOOL_VAR("diff", true), + CONF_END() +}; + +const struct default_config_item help_config_items[] = { + CONF_STR_VAR("format", "man"), + CONF_INT_VAR("autocorrect", 0), + CONF_END() +}; + +const struct default_config_item hist_config_items[] = { + CONF_STR_VAR("percentage", "absolute"), + CONF_END() +}; + +const struct default_config_item ui_config_items[] = { + CONF_BOOL_VAR("show-headers", true), + CONF_END() +}; + +const struct default_config_item call_graph_config_items[] = { + CONF_STR_VAR("record-mode", "fp"), + CONF_LONG_VAR("dump-size", 8192), + CONF_STR_VAR("print-type", "graph"), + CONF_STR_VAR("order", "callee"), + CONF_STR_VAR("sort-key", "function"), + CONF_DOUBLE_VAR("threshold", 0.5), + CONF_LONG_VAR("print-limit", 0), + CONF_END() +}; + +const struct default_config_item report_config_items[] = { + CONF_BOOL_VAR("group", true), + CONF_BOOL_VAR("children", true), + CONF_FLOAT_VAR("percent-limit", 0), + CONF_U64_VAR("queue-size", 0), + CONF_END() +}; + +
[PATCH v2 4/4] perf config: Initialize annotate_browser__opts with default config items
Set default config values for 'annotate' section with 'annotate_config_items[]' instead of actual bool type values. (e.g. using annotate_config_items[CONFIG_ANNOTATE_USE_OFFSET].value instead of 'true' bool type value for 'annotate.use_offset'.) Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browsers/annotate.c | 12 tools/perf/util/config.h | 16 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 4fc208e..f52e1ea 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -37,10 +37,7 @@ static struct annotate_browser_opt { show_linenr, show_nr_jumps, show_total_period; -} annotate_browser__opts = { - .use_offset = true, - .jump_arrows= true, -}; +} annotate_browser__opts; struct annotate_browser { struct ui_browser b; @@ -1160,5 +1157,12 @@ static int annotate__config(const char *var, const char *value, void annotate_browser__init(void) { + annotate_browser__opts.hide_src_code = CONF_ANNOTATE_DEFAULT_VAL(HIDE_SRC_CODE, b); + annotate_browser__opts.use_offset = CONF_ANNOTATE_DEFAULT_VAL(USE_OFFSET, b); + annotate_browser__opts.jump_arrows = CONF_ANNOTATE_DEFAULT_VAL(JUMP_ARROWS, b); + annotate_browser__opts.show_linenr = CONF_ANNOTATE_DEFAULT_VAL(SHOW_LINENR, b); + annotate_browser__opts.show_nr_jumps = CONF_ANNOTATE_DEFAULT_VAL(SHOW_NR_JUMPS, b); + annotate_browser__opts.show_total_period = CONF_ANNOTATE_DEFAULT_VAL(SHOW_TOTAL_PERIOD, b); + perf_config(annotate__config, NULL); } diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index e0c8392..344b344 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -54,6 +54,15 @@ enum colors_config_items_idx { CONFIG_COLORS_ROOT, }; +enum annotate_config_items_idx { + 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, +}; + #define CONF_VAR(_name, _field, _val, _type) \ { .name = _name, .value._field = _val, .type = _type } @@ -74,7 +83,14 @@ enum colors_config_items_idx { #define CONF_END() \ { .name = NULL } +#define CONF_DEFAULT_VAL(section, name, field) \ + section##_config_items[CONFIG_##name].value.field + +#define CONF_ANNOTATE_DEFAULT_VAL(name, field) \ + CONF_DEFAULT_VAL(annotate, ANNOTATE_##name, field) + extern const struct default_config_item colors_config_items[]; +extern const struct default_config_item annotate_config_items[]; struct perf_config_set *perf_config_set__new(void); void perf_config_set__delete(struct perf_config_set *set); -- 2.5.0
[PATCH v2 3/4] perf config: Initialize ui_browser__colorsets with default config items
Set default config values for 'colors' section with 'colors_config_items[]' instead of actual const char * type values. (e.g. using colors_config_item[CONFIG_COLORS_TOP].value instead of "red, default" string value for 'colors.top') Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browser.c | 46 -- tools/perf/ui/browser.h | 1 + tools/perf/ui/tui/setup.c | 1 + tools/perf/util/cache.h | 1 + tools/perf/util/config.h | 12 5 files changed, 47 insertions(+), 14 deletions(-) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index c905445..7b5d64b 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -509,44 +509,30 @@ static struct ui_browser_colorset { { .colorset = HE_COLORSET_TOP, .name = "top", - .fg = "red", - .bg = "default", }, { .colorset = HE_COLORSET_MEDIUM, .name = "medium", - .fg = "green", - .bg = "default", }, { .colorset = HE_COLORSET_NORMAL, .name = "normal", - .fg = "default", - .bg = "default", }, { .colorset = HE_COLORSET_SELECTED, .name = "selected", - .fg = "black", - .bg = "yellow", }, { .colorset = HE_COLORSET_JUMP_ARROWS, .name = "jump_arrows", - .fg = "blue", - .bg = "default", }, { .colorset = HE_COLORSET_ADDR, .name = "addr", - .fg = "magenta", - .bg = "default", }, { .colorset = HE_COLORSET_ROOT, .name = "root", - .fg = "white", - .bg = "blue", }, { .name = NULL, @@ -589,6 +575,7 @@ static int ui_browser__color_config(const char *var, const char *value, if (strcmp(ui_browser__colorsets[i].name, name) != 0) continue; + zfree((char **)&ui_browser__colorsets[i].fg); ret = ui_browser__config_colors(&ui_browser__colorsets[i], value); break; } @@ -743,10 +730,41 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, __ui_browser__line_arrow_down(browser, column, start, end); } +static void ui_browser__free_color_configs(void) +{ + int i; + + for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) + zfree((char **)&ui_browser__colorsets[i].fg); +} + +void ui_browser__free(void) +{ + ui_browser__free_color_configs(); +} + +static void ui_browser__init_colorsets(void) +{ + int i, j; + + for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) { + const char *name = ui_browser__colorsets[i].name; + + for (j = 0; colors_config_items[j].name != NULL; j++) { + if (!strcmp(name, colors_config_items[j].name)) { + ui_browser__config_colors(&ui_browser__colorsets[i], + colors_config_items[j].value.s); + break; + } + } + } +} + void ui_browser__init(void) { int i = 0; + ui_browser__init_colorsets(); perf_config(ui_browser__color_config, NULL); while (ui_browser__colorsets[i].name) { diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index be3b70e..7a83a1a 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h @@ -74,5 +74,6 @@ void ui_browser__list_head_seek(struct ui_browser *browser, off_t offset, int wh unsigned int ui_browser__list_head_refresh(struct ui_browser *browser); void ui_browser__init(void); +void ui_browser__free(void); void annotate_browser__init(void); #endif /* _PERF_UI_BROWSER_H_ */ diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index 7dfeba0..7999a57 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -171,4 +171,5 @@ void ui__exit(bool wait_for_ok) SLang_reset_tty(); perf_error__unregister(&perf_tui_eops); + ui_browser__free(); } diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 1f5a93c..8eab653 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -7,6 +7,7 @@ #in
[PATCH v2 0/4] perf config: Introduce default config key-value pairs arrays
We currently use values of actual type(int, bool, char *, etc.) when initializing default perf config values. For example, If there isn't user config value at ~/.perfconfig for 'annotate.use_offset' config variable, default value for it is 'true' bool type value in perf like below. At ui/browsers/annoate.c static struct annotate_browser_opt { bool hide_src_code, use_offset, jump_arrows, show_linenr, show_nr_jumps, show_total_period; } annotate_browser__opts = { .use_offset = true, .jump_arrows = true, }; But I suggest using new config arrays that have all default config key-value pairs and then initializing default config values with them. Because if we do, we can manage default perf config values at one spot (like util/config.c) and It can be easy and simple to modify default config values or add new configs. For example, If we use new default config arrays and there isn't user config value for 'annoate.use_offset' default value for it will be set as annotate_config_items[CONFIG_ANNOATE_USE_OFFSET].value instead of actual boolean type value 'true'. IMHO, I think it should be needed to use new default config arrays to manage default perf config values more effectively. And this pathset contains patchs for only 'colors' and 'annoate' section because waiting for other opinions. If you review this patchset, I'd appreciate it :-) Thanks, Taeung v2: - rename 'ui_browser__config_gcolors' to 'ui_browser__config_colors' (Arnaldo) - change 'ground colors' to '{back, fore}ground colors' (Arnaldo) - use strtok + ltrim instead of strchr and while (isspace(*++bg)); (Arnaldo) Taeung Song (4): perf config: Introduce default_config_item for all default config key-value pairs perf tools: Separate out code setting {back, fore}ground colors from ui_browser__color_config perf config: Initialize ui_browser__colorsets with default config items perf config: Initialize annotate_browser__opts with default config items tools/perf/ui/browser.c | 87 ++ tools/perf/ui/browser.h | 1 + tools/perf/ui/browsers/annotate.c | 12 ++- tools/perf/ui/tui/setup.c | 1 + tools/perf/util/cache.h | 1 + tools/perf/util/config.c | 150 +- tools/perf/util/config.h | 74 ++- 7 files changed, 289 insertions(+), 37 deletions(-) -- 2.5.0
[PATCH v2 2/4] perf tools: Separate out code setting {back, fore}ground colors from ui_browser__color_config
ui_browser__color_config() set foreground and background colors values in ui_browser__colorsets. But it can be reused by other functions so make ui_browser__config_colors() bringing it from ui_browser__color_config(). Cc: Namhyung Kim Cc: Jiri Olsa Signed-off-by: Taeung Song --- tools/perf/ui/browser.c | 41 - 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index af68a9d..c905445 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -553,12 +553,31 @@ static struct ui_browser_colorset { } }; +static int ui_browser__config_colors(struct ui_browser_colorset *ui_browser_color, +const char *value) +{ + char *fg = NULL, *bg; + + fg = strdup(value); + if (fg == NULL) + return -1; + + bg = strtok(fg, ","); + if (bg == NULL) { + free(fg); + return -1; + } + ltrim(bg); + + ui_browser_color->fg = fg; + ui_browser_color->bg = bg; + return 0; +} static int ui_browser__color_config(const char *var, const char *value, void *data __maybe_unused) { - char *fg = NULL, *bg; - int i; + int i, ret; /* same dir for all commands */ if (prefixcmp(var, "colors.") != 0) @@ -570,23 +589,11 @@ static int ui_browser__color_config(const char *var, const char *value, if (strcmp(ui_browser__colorsets[i].name, name) != 0) continue; - fg = strdup(value); - if (fg == NULL) - break; - - bg = strchr(fg, ','); - if (bg == NULL) - break; - - *bg = '\0'; - while (isspace(*++bg)); - ui_browser__colorsets[i].bg = bg; - ui_browser__colorsets[i].fg = fg; - return 0; + ret = ui_browser__config_colors(&ui_browser__colorsets[i], value); + break; } - free(fg); - return -1; + return ret; } void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence) -- 2.5.0