summaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-10-23 08:32:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-23 08:32:18 -0400
commitc05f3642f4304dd081876e77a68555b6aba4483f (patch)
tree915baf10c3518d162c00e62b5d855cf92282ed79 /tools/perf/builtin-script.c
parent0200fbdd431519d730b5d399a12840ec832b27cc (diff)
parentdda93b45389f025fd3422d22cc31cc1ea6040305 (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "The main updates in this cycle were: - Lots of perf tooling changes too voluminous to list (big perf trace and perf stat improvements, lots of libtraceevent reorganization, etc.), so I'll list the authors and refer to the changelog for details: Benjamin Peterson, Jérémie Galarneau, Kim Phillips, Peter Zijlstra, Ravi Bangoria, Sangwon Hong, Sean V Kelley, Steven Rostedt, Thomas Gleixner, Ding Xiang, Eduardo Habkost, Thomas Richter, Andi Kleen, Sanskriti Sharma, Adrian Hunter, Tzvetomir Stoyanov, Arnaldo Carvalho de Melo, Jiri Olsa. ... with the bulk of the changes written by Jiri Olsa, Tzvetomir Stoyanov and Arnaldo Carvalho de Melo. - Continued intel_rdt work with a focus on playing well with perf events. This also imported some non-perf RDT work due to dependencies. (Reinette Chatre) - Implement counter freezing for Arch Perfmon v4 (Skylake and newer). This allows to speed up the PMI handler by avoiding unnecessary MSR writes and make it more accurate. (Andi Kleen) - kprobes cleanups and simplification (Masami Hiramatsu) - Intel Goldmont PMU updates (Kan Liang) - ... plus misc other fixes and updates" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (155 commits) kprobes/x86: Use preempt_enable() in optimized_callback() x86/intel_rdt: Prevent pseudo-locking from using stale pointers kprobes, x86/ptrace.h: Make regs_get_kernel_stack_nth() not fault on bad stack perf/x86/intel: Export mem events only if there's PEBS support x86/cpu: Drop pointless static qualifier in punit_dev_state_show() x86/intel_rdt: Fix initial allocation to consider CDP x86/intel_rdt: CBM overlap should also check for overlap with CDP peer x86/intel_rdt: Introduce utility to obtain CDP peer tools lib traceevent, perf tools: Move struct tep_handler definition in a local header file tools lib traceevent: Separate out tep_strerror() for strerror_r() issues perf python: More portable way to make CFLAGS work with clang perf python: Make clang_has_option() work on Python 3 perf tools: Free temporary 'sys' string in read_event_files() perf tools: Avoid double free in read_event_file() perf tools: Free 'printk' string in parse_ftrace_printk() perf tools: Cleanup trace-event-info 'tdata' leak perf strbuf: Match va_{add,copy} with va_end perf test: S390 does not support watchpoints in test 22 perf auxtrace: Include missing asm/bitsperlong.h to get BITS_PER_LONG tools include: Adopt linux/bits.h ...
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c110
1 files changed, 69 insertions, 41 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index ba481d73f910..4da5e32b9e03 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -406,9 +406,10 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
406 PERF_OUTPUT_WEIGHT)) 406 PERF_OUTPUT_WEIGHT))
407 return -EINVAL; 407 return -EINVAL;
408 408
409 if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 409 if (PRINT_FIELD(SYM) &&
410 !(evsel->attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
410 pr_err("Display of symbols requested but neither sample IP nor " 411 pr_err("Display of symbols requested but neither sample IP nor "
411 "sample address\nis selected. Hence, no addresses to convert " 412 "sample address\navailable. Hence, no addresses to convert "
412 "to symbols.\n"); 413 "to symbols.\n");
413 return -EINVAL; 414 return -EINVAL;
414 } 415 }
@@ -417,10 +418,9 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
417 "selected.\n"); 418 "selected.\n");
418 return -EINVAL; 419 return -EINVAL;
419 } 420 }
420 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR) && 421 if (PRINT_FIELD(DSO) &&
421 !PRINT_FIELD(BRSTACK) && !PRINT_FIELD(BRSTACKSYM) && !PRINT_FIELD(BRSTACKOFF)) { 422 !(evsel->attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
422 pr_err("Display of DSO requested but no address to convert. Select\n" 423 pr_err("Display of DSO requested but no address to convert.\n");
423 "sample IP, sample address, brstack, brstacksym, or brstackoff.\n");
424 return -EINVAL; 424 return -EINVAL;
425 } 425 }
426 if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) { 426 if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) {
@@ -1115,6 +1115,7 @@ static int perf_sample__fprintf_callindent(struct perf_sample *sample,
1115 const char *name = NULL; 1115 const char *name = NULL;
1116 static int spacing; 1116 static int spacing;
1117 int len = 0; 1117 int len = 0;
1118 int dlen = 0;
1118 u64 ip = 0; 1119 u64 ip = 0;
1119 1120
1120 /* 1121 /*
@@ -1141,6 +1142,12 @@ static int perf_sample__fprintf_callindent(struct perf_sample *sample,
1141 ip = sample->ip; 1142 ip = sample->ip;
1142 } 1143 }
1143 1144
1145 if (PRINT_FIELD(DSO) && !(PRINT_FIELD(IP) || PRINT_FIELD(ADDR))) {
1146 dlen += fprintf(fp, "(");
1147 dlen += map__fprintf_dsoname(al->map, fp);
1148 dlen += fprintf(fp, ")\t");
1149 }
1150
1144 if (name) 1151 if (name)
1145 len = fprintf(fp, "%*s%s", (int)depth * 4, "", name); 1152 len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
1146 else if (ip) 1153 else if (ip)
@@ -1159,7 +1166,7 @@ static int perf_sample__fprintf_callindent(struct perf_sample *sample,
1159 if (len < spacing) 1166 if (len < spacing)
1160 len += fprintf(fp, "%*s", spacing - len, ""); 1167 len += fprintf(fp, "%*s", spacing - len, "");
1161 1168
1162 return len; 1169 return len + dlen;
1163} 1170}
1164 1171
1165static int perf_sample__fprintf_insn(struct perf_sample *sample, 1172static int perf_sample__fprintf_insn(struct perf_sample *sample,
@@ -1255,6 +1262,18 @@ static struct {
1255 {0, NULL} 1262 {0, NULL}
1256}; 1263};
1257 1264
1265static const char *sample_flags_to_name(u32 flags)
1266{
1267 int i;
1268
1269 for (i = 0; sample_flags[i].name ; i++) {
1270 if (sample_flags[i].flags == flags)
1271 return sample_flags[i].name;
1272 }
1273
1274 return NULL;
1275}
1276
1258static int perf_sample__fprintf_flags(u32 flags, FILE *fp) 1277static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
1259{ 1278{
1260 const char *chars = PERF_IP_FLAG_CHARS; 1279 const char *chars = PERF_IP_FLAG_CHARS;
@@ -1264,11 +1283,20 @@ static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
1264 char str[33]; 1283 char str[33];
1265 int i, pos = 0; 1284 int i, pos = 0;
1266 1285
1267 for (i = 0; sample_flags[i].name ; i++) { 1286 name = sample_flags_to_name(flags & ~PERF_IP_FLAG_IN_TX);
1268 if (sample_flags[i].flags == (flags & ~PERF_IP_FLAG_IN_TX)) { 1287 if (name)
1269 name = sample_flags[i].name; 1288 return fprintf(fp, " %-15s%4s ", name, in_tx ? "(x)" : "");
1270 break; 1289
1271 } 1290 if (flags & PERF_IP_FLAG_TRACE_BEGIN) {
1291 name = sample_flags_to_name(flags & ~(PERF_IP_FLAG_IN_TX | PERF_IP_FLAG_TRACE_BEGIN));
1292 if (name)
1293 return fprintf(fp, " tr strt %-7s%4s ", name, in_tx ? "(x)" : "");
1294 }
1295
1296 if (flags & PERF_IP_FLAG_TRACE_END) {
1297 name = sample_flags_to_name(flags & ~(PERF_IP_FLAG_IN_TX | PERF_IP_FLAG_TRACE_END));
1298 if (name)
1299 return fprintf(fp, " tr end %-7s%4s ", name, in_tx ? "(x)" : "");
1272 } 1300 }
1273 1301
1274 for (i = 0; i < n; i++, flags >>= 1) { 1302 for (i = 0; i < n; i++, flags >>= 1) {
@@ -1281,10 +1309,7 @@ static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
1281 } 1309 }
1282 str[pos] = 0; 1310 str[pos] = 0;
1283 1311
1284 if (name) 1312 return fprintf(fp, " %-19s ", str);
1285 return fprintf(fp, " %-7s%4s ", name, in_tx ? "(x)" : "");
1286
1287 return fprintf(fp, " %-11s ", str);
1288} 1313}
1289 1314
1290struct printer_data { 1315struct printer_data {
@@ -1544,7 +1569,8 @@ struct metric_ctx {
1544 FILE *fp; 1569 FILE *fp;
1545}; 1570};
1546 1571
1547static void script_print_metric(void *ctx, const char *color, 1572static void script_print_metric(struct perf_stat_config *config __maybe_unused,
1573 void *ctx, const char *color,
1548 const char *fmt, 1574 const char *fmt,
1549 const char *unit, double val) 1575 const char *unit, double val)
1550{ 1576{
@@ -1562,7 +1588,8 @@ static void script_print_metric(void *ctx, const char *color,
1562 fprintf(mctx->fp, " %s\n", unit); 1588 fprintf(mctx->fp, " %s\n", unit);
1563} 1589}
1564 1590
1565static void script_new_line(void *ctx) 1591static void script_new_line(struct perf_stat_config *config __maybe_unused,
1592 void *ctx)
1566{ 1593{
1567 struct metric_ctx *mctx = ctx; 1594 struct metric_ctx *mctx = ctx;
1568 1595
@@ -1608,7 +1635,7 @@ static void perf_sample__fprint_metric(struct perf_script *script,
1608 evsel_script(evsel)->val = val; 1635 evsel_script(evsel)->val = val;
1609 if (evsel_script(evsel->leader)->gnum == evsel->leader->nr_members) { 1636 if (evsel_script(evsel->leader)->gnum == evsel->leader->nr_members) {
1610 for_each_group_member (ev2, evsel->leader) { 1637 for_each_group_member (ev2, evsel->leader) {
1611 perf_stat__print_shadow_stats(ev2, 1638 perf_stat__print_shadow_stats(&stat_config, ev2,
1612 evsel_script(ev2)->val, 1639 evsel_script(ev2)->val,
1613 sample->cpu, 1640 sample->cpu,
1614 &ctx, 1641 &ctx,
@@ -2489,6 +2516,8 @@ parse:
2489 output[j].fields &= ~all_output_options[i].field; 2516 output[j].fields &= ~all_output_options[i].field;
2490 else 2517 else
2491 output[j].fields |= all_output_options[i].field; 2518 output[j].fields |= all_output_options[i].field;
2519 output[j].user_set = true;
2520 output[j].wildcard_set = true;
2492 } 2521 }
2493 } 2522 }
2494 } else { 2523 } else {
@@ -2499,7 +2528,8 @@ parse:
2499 rc = -EINVAL; 2528 rc = -EINVAL;
2500 goto out; 2529 goto out;
2501 } 2530 }
2502 output[type].fields |= all_output_options[i].field; 2531 output[type].user_set = true;
2532 output[type].wildcard_set = true;
2503 } 2533 }
2504 } 2534 }
2505 2535
@@ -2963,9 +2993,8 @@ static void script__setup_sample_type(struct perf_script *script)
2963 } 2993 }
2964} 2994}
2965 2995
2966static int process_stat_round_event(struct perf_tool *tool __maybe_unused, 2996static int process_stat_round_event(struct perf_session *session,
2967 union perf_event *event, 2997 union perf_event *event)
2968 struct perf_session *session)
2969{ 2998{
2970 struct stat_round_event *round = &event->stat_round; 2999 struct stat_round_event *round = &event->stat_round;
2971 struct perf_evsel *counter; 3000 struct perf_evsel *counter;
@@ -2979,9 +3008,8 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
2979 return 0; 3008 return 0;
2980} 3009}
2981 3010
2982static int process_stat_config_event(struct perf_tool *tool __maybe_unused, 3011static int process_stat_config_event(struct perf_session *session __maybe_unused,
2983 union perf_event *event, 3012 union perf_event *event)
2984 struct perf_session *session __maybe_unused)
2985{ 3013{
2986 perf_event__read_stat_config(&stat_config, &event->stat_config); 3014 perf_event__read_stat_config(&stat_config, &event->stat_config);
2987 return 0; 3015 return 0;
@@ -3007,10 +3035,10 @@ static int set_maps(struct perf_script *script)
3007} 3035}
3008 3036
3009static 3037static
3010int process_thread_map_event(struct perf_tool *tool, 3038int process_thread_map_event(struct perf_session *session,
3011 union perf_event *event, 3039 union perf_event *event)
3012 struct perf_session *session __maybe_unused)
3013{ 3040{
3041 struct perf_tool *tool = session->tool;
3014 struct perf_script *script = container_of(tool, struct perf_script, tool); 3042 struct perf_script *script = container_of(tool, struct perf_script, tool);
3015 3043
3016 if (script->threads) { 3044 if (script->threads) {
@@ -3026,10 +3054,10 @@ int process_thread_map_event(struct perf_tool *tool,
3026} 3054}
3027 3055
3028static 3056static
3029int process_cpu_map_event(struct perf_tool *tool __maybe_unused, 3057int process_cpu_map_event(struct perf_session *session,
3030 union perf_event *event, 3058 union perf_event *event)
3031 struct perf_session *session __maybe_unused)
3032{ 3059{
3060 struct perf_tool *tool = session->tool;
3033 struct perf_script *script = container_of(tool, struct perf_script, tool); 3061 struct perf_script *script = container_of(tool, struct perf_script, tool);
3034 3062
3035 if (script->cpus) { 3063 if (script->cpus) {
@@ -3044,21 +3072,21 @@ int process_cpu_map_event(struct perf_tool *tool __maybe_unused,
3044 return set_maps(script); 3072 return set_maps(script);
3045} 3073}
3046 3074
3047static int process_feature_event(struct perf_tool *tool, 3075static int process_feature_event(struct perf_session *session,
3048 union perf_event *event, 3076 union perf_event *event)
3049 struct perf_session *session)
3050{ 3077{
3051 if (event->feat.feat_id < HEADER_LAST_FEATURE) 3078 if (event->feat.feat_id < HEADER_LAST_FEATURE)
3052 return perf_event__process_feature(tool, event, session); 3079 return perf_event__process_feature(session, event);
3053 return 0; 3080 return 0;
3054} 3081}
3055 3082
3056#ifdef HAVE_AUXTRACE_SUPPORT 3083#ifdef HAVE_AUXTRACE_SUPPORT
3057static int perf_script__process_auxtrace_info(struct perf_tool *tool, 3084static int perf_script__process_auxtrace_info(struct perf_session *session,
3058 union perf_event *event, 3085 union perf_event *event)
3059 struct perf_session *session)
3060{ 3086{
3061 int ret = perf_event__process_auxtrace_info(tool, event, session); 3087 struct perf_tool *tool = session->tool;
3088
3089 int ret = perf_event__process_auxtrace_info(session, event);
3062 3090
3063 if (ret == 0) { 3091 if (ret == 0) {
3064 struct perf_script *script = container_of(tool, struct perf_script, tool); 3092 struct perf_script *script = container_of(tool, struct perf_script, tool);
@@ -3193,7 +3221,7 @@ int cmd_script(int argc, const char **argv)
3193 OPT_BOOLEAN(0, "ns", &nanosecs, 3221 OPT_BOOLEAN(0, "ns", &nanosecs,
3194 "Use 9 decimal places when displaying time"), 3222 "Use 9 decimal places when displaying time"),
3195 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", 3223 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
3196 "Instruction Tracing options", 3224 "Instruction Tracing options\n" ITRACE_HELP,
3197 itrace_parse_synth_opts), 3225 itrace_parse_synth_opts),
3198 OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename, 3226 OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
3199 "Show full source file name path for source lines"), 3227 "Show full source file name path for source lines"),