diff --git a/tools/perf/Documentation/perf-kmem.txt b/tools/perf/Documentation/perf-kmem.txt index 44b0ce35c28..eac4d852e7c 100644 --- a/tools/perf/Documentation/perf-kmem.txt +++ b/tools/perf/Documentation/perf-kmem.txt @@ -8,16 +8,16 @@ perf-kmem - Tool to trace/measure kernel memory(slab) properties SYNOPSIS -------- [verse] -'perf kmem' {record} [] +'perf kmem' {record|stat} [] DESCRIPTION ----------- -There's two variants of perf kmem: +There are two variants of perf kmem: 'perf kmem record ' to record the kmem events of an arbitrary workload. - 'perf kmem' to report kernel memory statistics. + 'perf kmem stat' to report kernel memory statistics. OPTIONS ------- @@ -25,8 +25,11 @@ OPTIONS --input=:: Select the input file (default: perf.data) ---stat=:: - Select per callsite or per allocation statistics +--caller:: + Show per-callsite statistics + +--alloc:: + Show per-allocation statistics -s :: --sort=:: diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 7551a5f834b..1b04787ed90 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -526,7 +526,7 @@ static int __cmd_kmem(void) } static const char * const kmem_usage[] = { - "perf kmem [] {record}", + "perf kmem [] {record|stat}", NULL }; @@ -686,18 +686,17 @@ static int parse_sort_opt(const struct option *opt __used, return 0; } -static int parse_stat_opt(const struct option *opt __used, +static int parse_caller_opt(const struct option *opt __used, const char *arg, int unset __used) { - if (!arg) - return -1; + caller_flag = (alloc_flag + 1); + return 0; +} - if (strcmp(arg, "alloc") == 0) - alloc_flag = (caller_flag + 1); - else if (strcmp(arg, "caller") == 0) - caller_flag = (alloc_flag + 1); - else - return -1; +static int parse_alloc_opt(const struct option *opt __used, + const char *arg, int unset __used) +{ + alloc_flag = (caller_flag + 1); return 0; } @@ -722,14 +721,17 @@ static int parse_line_opt(const struct option *opt __used, static const struct option kmem_options[] = { OPT_STRING('i', "input", &input_name, "file", "input file name"), - OPT_CALLBACK(0, "stat", NULL, "|", - "stat selector, Pass 'alloc' or 'caller'.", - parse_stat_opt), + OPT_CALLBACK_NOOPT(0, "caller", NULL, NULL, + "show per-callsite statistics", + parse_caller_opt), + OPT_CALLBACK_NOOPT(0, "alloc", NULL, NULL, + "show per-allocation statistics", + parse_alloc_opt), OPT_CALLBACK('s', "sort", NULL, "key[,key2...]", "sort by keys: ptr, call_site, bytes, hit, pingpong, frag", parse_sort_opt), OPT_CALLBACK('l', "line", NULL, "num", - "show n lins", + "show n lines", parse_line_opt), OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"), OPT_END() @@ -773,18 +775,22 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __used) argc = parse_options(argc, argv, kmem_options, kmem_usage, 0); - if (argc && !strncmp(argv[0], "rec", 3)) - return __cmd_record(argc, argv); - else if (argc) + if (!argc) usage_with_options(kmem_usage, kmem_options); - if (list_empty(&caller_sort)) - setup_sorting(&caller_sort, default_sort_order); - if (list_empty(&alloc_sort)) - setup_sorting(&alloc_sort, default_sort_order); + if (!strncmp(argv[0], "rec", 3)) { + return __cmd_record(argc, argv); + } else if (!strcmp(argv[0], "stat")) { + setup_cpunode_map(); - setup_cpunode_map(); + if (list_empty(&caller_sort)) + setup_sorting(&caller_sort, default_sort_order); + if (list_empty(&alloc_sort)) + setup_sorting(&alloc_sort, default_sort_order); - return __cmd_kmem(); + return __cmd_kmem(); + } + + return 0; }