Em Wed, Aug 05, 2020 at 11:34:44AM +0200, Jiri Olsa escreveu: > Adding tod field to display time of day column with > time of date (wallclock) time. > > # perf record -k CLOCK_MONOTONIC kill > kill: not enough arguments > [ perf record: Woken up 1 times to write data ] > [ perf record: Captured and wrote 0.033 MB perf.data (8 samples) ]
Thanks, applied. - Arnaldo > # perf script > perf 261340 152919.481538: 1 cycles: ffffffff8106d104 > ... > perf 261340 152919.481543: 1 cycles: ffffffff8106d104 > ... > perf 261340 152919.481545: 7 cycles: ffffffff8106d104 > ... > ... > > # perf script --ns > perf 261340 152919.481538922: 1 cycles: ffffffff8106d > ... > perf 261340 152919.481543286: 1 cycles: ffffffff8106d > ... > perf 261340 152919.481545397: 7 cycles: ffffffff8106d > ... > ... > > # perf script -F+tod > perf 261340 2020-07-13 18:26:55.620971 152919.481538: > ... > perf 261340 2020-07-13 18:26:55.620975 152919.481543: > ... > perf 261340 2020-07-13 18:26:55.620978 152919.481545: > ... > ... > > # perf script -F+tod --ns > perf 261340 2020-07-13 18:26:55.620971621 152919.481538922: > ... > perf 261340 2020-07-13 18:26:55.620975985 152919.481543286: > ... > perf 261340 2020-07-13 18:26:55.620978096 152919.481545397: > ... > ... > > It's available only for recording with clockid specified, > because it's the only case where we can get reference time > to wallclock time. It's can't do that with perf clock yet. > > Error is display if you want to use --tod on data without > clockid specified: > > # perf script -F+tod > Can't provide 'tod' time, missing clock data. Please record with > -k/--clockid option. > > Original-patch-by: David Ahern <dsah...@gmail.com> > Signed-off-by: Jiri Olsa <jo...@kernel.org> > --- > tools/perf/builtin-script.c | 131 +++++++++++++++++++++++++++--------- > 1 file changed, 98 insertions(+), 33 deletions(-) > > diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c > index eb45f678dc2f..484ce6067d23 100644 > --- a/tools/perf/builtin-script.c > +++ b/tools/perf/builtin-script.c > @@ -114,6 +114,32 @@ enum perf_output_field { > PERF_OUTPUT_MISC = 1ULL << 29, > PERF_OUTPUT_SRCCODE = 1ULL << 30, > PERF_OUTPUT_IPC = 1ULL << 31, > + PERF_OUTPUT_TOD = 1ULL << 32, > +}; > + > +struct perf_script { > + struct perf_tool tool; > + struct perf_session *session; > + bool show_task_events; > + bool show_mmap_events; > + bool show_switch_events; > + bool show_namespace_events; > + bool show_lost_events; > + bool show_round_events; > + bool show_bpf_events; > + bool show_cgroup_events; > + bool show_text_poke_events; > + bool allocated; > + bool per_event_dump; > + bool stitch_lbr; > + struct evswitch evswitch; > + struct perf_cpu_map *cpus; > + struct perf_thread_map *threads; > + int name_width; > + const char *time_str; > + struct perf_time_interval *ptime_range; > + int range_size; > + int range_num; > }; > > struct output_option { > @@ -152,6 +178,7 @@ struct output_option { > {.str = "misc", .field = PERF_OUTPUT_MISC}, > {.str = "srccode", .field = PERF_OUTPUT_SRCCODE}, > {.str = "ipc", .field = PERF_OUTPUT_IPC}, > + {.str = "tod", .field = PERF_OUTPUT_TOD}, > }; > > enum { > @@ -502,6 +529,7 @@ static void set_print_ip_opts(struct perf_event_attr > *attr) > */ > static int perf_session__check_output_opt(struct perf_session *session) > { > + bool tod = false; > unsigned int j; > struct evsel *evsel; > > @@ -528,6 +556,7 @@ static int perf_session__check_output_opt(struct > perf_session *session) > continue; > > set_print_ip_opts(&evsel->core.attr); > + tod |= output[j].fields & PERF_OUTPUT_TOD; > } > > if (!no_callchain) { > @@ -568,13 +597,17 @@ static int perf_session__check_output_opt(struct > perf_session *session) > } > } > > + if (tod && !session->header.env.clock.enabled) { > + pr_err("Can't provide 'tod' time, missing clock data. " > + "Please record with -k/--clockid option.\n"); > + return -1; > + } > out: > return 0; > } > > static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, > - FILE *fp > -) > + FILE *fp) > { > unsigned i = 0, r; > int printed = 0; > @@ -592,6 +625,56 @@ static int perf_sample__fprintf_regs(struct regs_dump > *regs, uint64_t mask, > return printed; > } > > +#define DEFAULT_TOD_FMT "%F %H:%M:%S" > + > +static char* > +tod_scnprintf(struct perf_script *script, char *buf, int buflen, > + u64 timestamp) > +{ > + u64 tod_ns, clockid_ns; > + struct perf_env *env; > + unsigned long nsec; > + struct tm ltime; > + char date[64]; > + time_t sec; > + > + buf[0] = '\0'; > + if (buflen < 64 || !script) > + return buf; > + > + env = &script->session->header.env; > + if (!env->clock.enabled) { > + scnprintf(buf, buflen, "disabled"); > + return buf; > + } > + > + clockid_ns = env->clock.clockid_ns; > + tod_ns = env->clock.tod_ns; > + > + if (timestamp > clockid_ns) > + tod_ns += timestamp - clockid_ns; > + else > + tod_ns -= clockid_ns - timestamp; > + > + sec = (time_t) (tod_ns / NSEC_PER_SEC); > + nsec = tod_ns - sec * NSEC_PER_SEC; > + > + if (localtime_r(&sec, <ime) == NULL) { > + scnprintf(buf, buflen, "failed"); > + } else { > + strftime(date, sizeof(date), DEFAULT_TOD_FMT, <ime); > + > + if (symbol_conf.nanosecs) { > + snprintf(buf, buflen, "%s.%09lu", date, nsec); > + } else { > + snprintf(buf, buflen, "%s.%06lu", > + date, nsec / NSEC_PER_USEC); > + } > + } > + > + return buf; > +} > + > static int perf_sample__fprintf_iregs(struct perf_sample *sample, > struct perf_event_attr *attr, FILE *fp) > { > @@ -606,7 +689,8 @@ static int perf_sample__fprintf_uregs(struct perf_sample > *sample, > attr->sample_regs_user, fp); > } > > -static int perf_sample__fprintf_start(struct perf_sample *sample, > +static int perf_sample__fprintf_start(struct perf_script *script, > + struct perf_sample *sample, > struct thread *thread, > struct evsel *evsel, > u32 type, FILE *fp) > @@ -615,6 +699,7 @@ static int perf_sample__fprintf_start(struct perf_sample > *sample, > unsigned long secs; > unsigned long long nsecs; > int printed = 0; > + char tstr[128]; > > if (PRINT_FIELD(COMM)) { > if (latency_format) > @@ -683,6 +768,11 @@ static int perf_sample__fprintf_start(struct perf_sample > *sample, > printed += ret; > } > > + if (PRINT_FIELD(TOD)) { > + tod_scnprintf(script, tstr, sizeof(tstr), sample->time); > + printed += fprintf(fp, "%s ", tstr); > + } > + > if (PRINT_FIELD(TIME)) { > u64 t = sample->time; > if (reltime) { > @@ -1667,31 +1757,6 @@ static int perf_sample__fprintf_synth(struct > perf_sample *sample, > return 0; > } > > -struct perf_script { > - struct perf_tool tool; > - struct perf_session *session; > - bool show_task_events; > - bool show_mmap_events; > - bool show_switch_events; > - bool show_namespace_events; > - bool show_lost_events; > - bool show_round_events; > - bool show_bpf_events; > - bool show_cgroup_events; > - bool show_text_poke_events; > - bool allocated; > - bool per_event_dump; > - bool stitch_lbr; > - struct evswitch evswitch; > - struct perf_cpu_map *cpus; > - struct perf_thread_map *threads; > - int name_width; > - const char *time_str; > - struct perf_time_interval *ptime_range; > - int range_size; > - int range_num; > -}; > - > static int evlist__max_name_len(struct evlist *evlist) > { > struct evsel *evsel; > @@ -1739,7 +1804,7 @@ static void script_print_metric(struct perf_stat_config > *config __maybe_unused, > > if (!fmt) > return; > - perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel, > + perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, > mctx->evsel, > PERF_RECORD_SAMPLE, mctx->fp); > fputs("\tmetric: ", mctx->fp); > if (color) > @@ -1754,7 +1819,7 @@ static void script_new_line(struct perf_stat_config > *config __maybe_unused, > { > struct metric_ctx *mctx = ctx; > > - perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel, > + perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, > mctx->evsel, > PERF_RECORD_SAMPLE, mctx->fp); > fputs("\tmetric: ", mctx->fp); > } > @@ -1865,7 +1930,7 @@ static void process_event(struct perf_script *script, > > ++es->samples; > > - perf_sample__fprintf_start(sample, thread, evsel, > + perf_sample__fprintf_start(script, sample, thread, evsel, > PERF_RECORD_SAMPLE, fp); > > if (PRINT_FIELD(PERIOD)) > @@ -2174,7 +2239,7 @@ static int print_event_with_time(struct perf_tool *tool, > thread = machine__findnew_thread(machine, pid, tid); > > if (thread && evsel) { > - perf_sample__fprintf_start(sample, thread, evsel, > + perf_sample__fprintf_start(script, sample, thread, evsel, > event->header.type, stdout); > } > > @@ -3439,7 +3504,7 @@ int cmd_script(int argc, const char **argv) > "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," > "addr,symoff,srcline,period,iregs,uregs,brstack," > "brstacksym,flags,bpf-output,brstackinsn,brstackoff," > - "callindent,insn,insnlen,synth,phys_addr,metric,misc,ipc", > + > "callindent,insn,insnlen,synth,phys_addr,metric,misc,ipc,tod", > parse_output_fields), > OPT_BOOLEAN('a', "all-cpus", &system_wide, > "system-wide collection from all CPUs"), > -- > 2.25.4 > -- - Arnaldo