aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c266
1 files changed, 229 insertions, 37 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 9b43bda45a41..ab19a6ee4093 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -22,9 +22,11 @@
22#include "util/cpumap.h" 22#include "util/cpumap.h"
23#include "util/thread_map.h" 23#include "util/thread_map.h"
24#include "util/stat.h" 24#include "util/stat.h"
25#include "util/color.h"
25#include "util/string2.h" 26#include "util/string2.h"
26#include "util/thread-stack.h" 27#include "util/thread-stack.h"
27#include "util/time-utils.h" 28#include "util/time-utils.h"
29#include "util/path.h"
28#include "print_binary.h" 30#include "print_binary.h"
29#include <linux/bitmap.h> 31#include <linux/bitmap.h>
30#include <linux/kernel.h> 32#include <linux/kernel.h>
@@ -40,6 +42,7 @@
40#include <sys/param.h> 42#include <sys/param.h>
41#include <sys/types.h> 43#include <sys/types.h>
42#include <sys/stat.h> 44#include <sys/stat.h>
45#include <fcntl.h>
43#include <unistd.h> 46#include <unistd.h>
44 47
45#include "sane_ctype.h" 48#include "sane_ctype.h"
@@ -90,6 +93,8 @@ enum perf_output_field {
90 PERF_OUTPUT_SYNTH = 1U << 25, 93 PERF_OUTPUT_SYNTH = 1U << 25,
91 PERF_OUTPUT_PHYS_ADDR = 1U << 26, 94 PERF_OUTPUT_PHYS_ADDR = 1U << 26,
92 PERF_OUTPUT_UREGS = 1U << 27, 95 PERF_OUTPUT_UREGS = 1U << 27,
96 PERF_OUTPUT_METRIC = 1U << 28,
97 PERF_OUTPUT_MISC = 1U << 29,
93}; 98};
94 99
95struct output_option { 100struct output_option {
@@ -124,6 +129,8 @@ struct output_option {
124 {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF}, 129 {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
125 {.str = "synth", .field = PERF_OUTPUT_SYNTH}, 130 {.str = "synth", .field = PERF_OUTPUT_SYNTH},
126 {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR}, 131 {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
132 {.str = "metric", .field = PERF_OUTPUT_METRIC},
133 {.str = "misc", .field = PERF_OUTPUT_MISC},
127}; 134};
128 135
129enum { 136enum {
@@ -215,12 +222,20 @@ struct perf_evsel_script {
215 char *filename; 222 char *filename;
216 FILE *fp; 223 FILE *fp;
217 u64 samples; 224 u64 samples;
225 /* For metric output */
226 u64 val;
227 int gnum;
218}; 228};
219 229
230static inline struct perf_evsel_script *evsel_script(struct perf_evsel *evsel)
231{
232 return (struct perf_evsel_script *)evsel->priv;
233}
234
220static struct perf_evsel_script *perf_evsel_script__new(struct perf_evsel *evsel, 235static struct perf_evsel_script *perf_evsel_script__new(struct perf_evsel *evsel,
221 struct perf_data *data) 236 struct perf_data *data)
222{ 237{
223 struct perf_evsel_script *es = malloc(sizeof(*es)); 238 struct perf_evsel_script *es = zalloc(sizeof(*es));
224 239
225 if (es != NULL) { 240 if (es != NULL) {
226 if (asprintf(&es->filename, "%s.%s.dump", data->file.path, perf_evsel__name(evsel)) < 0) 241 if (asprintf(&es->filename, "%s.%s.dump", data->file.path, perf_evsel__name(evsel)) < 0)
@@ -228,7 +243,6 @@ static struct perf_evsel_script *perf_evsel_script__new(struct perf_evsel *evsel
228 es->fp = fopen(es->filename, "w"); 243 es->fp = fopen(es->filename, "w");
229 if (es->fp == NULL) 244 if (es->fp == NULL)
230 goto out_free_filename; 245 goto out_free_filename;
231 es->samples = 0;
232 } 246 }
233 247
234 return es; 248 return es;
@@ -423,11 +437,6 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
423 PERF_OUTPUT_CPU, allow_user_set)) 437 PERF_OUTPUT_CPU, allow_user_set))
424 return -EINVAL; 438 return -EINVAL;
425 439
426 if (PRINT_FIELD(PERIOD) &&
427 perf_evsel__check_stype(evsel, PERF_SAMPLE_PERIOD, "PERIOD",
428 PERF_OUTPUT_PERIOD))
429 return -EINVAL;
430
431 if (PRINT_FIELD(IREGS) && 440 if (PRINT_FIELD(IREGS) &&
432 perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", 441 perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS",
433 PERF_OUTPUT_IREGS)) 442 PERF_OUTPUT_IREGS))
@@ -588,7 +597,8 @@ static int perf_sample__fprintf_uregs(struct perf_sample *sample,
588 597
589static int perf_sample__fprintf_start(struct perf_sample *sample, 598static int perf_sample__fprintf_start(struct perf_sample *sample,
590 struct thread *thread, 599 struct thread *thread,
591 struct perf_evsel *evsel, FILE *fp) 600 struct perf_evsel *evsel,
601 u32 type, FILE *fp)
592{ 602{
593 struct perf_event_attr *attr = &evsel->attr; 603 struct perf_event_attr *attr = &evsel->attr;
594 unsigned long secs; 604 unsigned long secs;
@@ -618,6 +628,47 @@ static int perf_sample__fprintf_start(struct perf_sample *sample,
618 printed += fprintf(fp, "[%03d] ", sample->cpu); 628 printed += fprintf(fp, "[%03d] ", sample->cpu);
619 } 629 }
620 630
631 if (PRINT_FIELD(MISC)) {
632 int ret = 0;
633
634 #define has(m) \
635 (sample->misc & PERF_RECORD_MISC_##m) == PERF_RECORD_MISC_##m
636
637 if (has(KERNEL))
638 ret += fprintf(fp, "K");
639 if (has(USER))
640 ret += fprintf(fp, "U");
641 if (has(HYPERVISOR))
642 ret += fprintf(fp, "H");
643 if (has(GUEST_KERNEL))
644 ret += fprintf(fp, "G");
645 if (has(GUEST_USER))
646 ret += fprintf(fp, "g");
647
648 switch (type) {
649 case PERF_RECORD_MMAP:
650 case PERF_RECORD_MMAP2:
651 if (has(MMAP_DATA))
652 ret += fprintf(fp, "M");
653 break;
654 case PERF_RECORD_COMM:
655 if (has(COMM_EXEC))
656 ret += fprintf(fp, "E");
657 break;
658 case PERF_RECORD_SWITCH:
659 case PERF_RECORD_SWITCH_CPU_WIDE:
660 if (has(SWITCH_OUT))
661 ret += fprintf(fp, "S");
662 default:
663 break;
664 }
665
666 #undef has
667
668 ret += fprintf(fp, "%*s", 6 - ret, " ");
669 printed += ret;
670 }
671
621 if (PRINT_FIELD(TIME)) { 672 if (PRINT_FIELD(TIME)) {
622 nsecs = sample->time; 673 nsecs = sample->time;
623 secs = nsecs / NSEC_PER_SEC; 674 secs = nsecs / NSEC_PER_SEC;
@@ -1437,13 +1488,16 @@ struct perf_script {
1437 bool show_mmap_events; 1488 bool show_mmap_events;
1438 bool show_switch_events; 1489 bool show_switch_events;
1439 bool show_namespace_events; 1490 bool show_namespace_events;
1491 bool show_lost_events;
1440 bool allocated; 1492 bool allocated;
1441 bool per_event_dump; 1493 bool per_event_dump;
1442 struct cpu_map *cpus; 1494 struct cpu_map *cpus;
1443 struct thread_map *threads; 1495 struct thread_map *threads;
1444 int name_width; 1496 int name_width;
1445 const char *time_str; 1497 const char *time_str;
1446 struct perf_time_interval ptime; 1498 struct perf_time_interval *ptime_range;
1499 int range_size;
1500 int range_num;
1447}; 1501};
1448 1502
1449static int perf_evlist__max_name_len(struct perf_evlist *evlist) 1503static int perf_evlist__max_name_len(struct perf_evlist *evlist)
@@ -1477,6 +1531,88 @@ static int data_src__fprintf(u64 data_src, FILE *fp)
1477 return fprintf(fp, "%-*s", maxlen, out); 1531 return fprintf(fp, "%-*s", maxlen, out);
1478} 1532}
1479 1533
1534struct metric_ctx {
1535 struct perf_sample *sample;
1536 struct thread *thread;
1537 struct perf_evsel *evsel;
1538 FILE *fp;
1539};
1540
1541static void script_print_metric(void *ctx, const char *color,
1542 const char *fmt,
1543 const char *unit, double val)
1544{
1545 struct metric_ctx *mctx = ctx;
1546
1547 if (!fmt)
1548 return;
1549 perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel,
1550 PERF_RECORD_SAMPLE, mctx->fp);
1551 fputs("\tmetric: ", mctx->fp);
1552 if (color)
1553 color_fprintf(mctx->fp, color, fmt, val);
1554 else
1555 printf(fmt, val);
1556 fprintf(mctx->fp, " %s\n", unit);
1557}
1558
1559static void script_new_line(void *ctx)
1560{
1561 struct metric_ctx *mctx = ctx;
1562
1563 perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel,
1564 PERF_RECORD_SAMPLE, mctx->fp);
1565 fputs("\tmetric: ", mctx->fp);
1566}
1567
1568static void perf_sample__fprint_metric(struct perf_script *script,
1569 struct thread *thread,
1570 struct perf_evsel *evsel,
1571 struct perf_sample *sample,
1572 FILE *fp)
1573{
1574 struct perf_stat_output_ctx ctx = {
1575 .print_metric = script_print_metric,
1576 .new_line = script_new_line,
1577 .ctx = &(struct metric_ctx) {
1578 .sample = sample,
1579 .thread = thread,
1580 .evsel = evsel,
1581 .fp = fp,
1582 },
1583 .force_header = false,
1584 };
1585 struct perf_evsel *ev2;
1586 static bool init;
1587 u64 val;
1588
1589 if (!init) {
1590 perf_stat__init_shadow_stats();
1591 init = true;
1592 }
1593 if (!evsel->stats)
1594 perf_evlist__alloc_stats(script->session->evlist, false);
1595 if (evsel_script(evsel->leader)->gnum++ == 0)
1596 perf_stat__reset_shadow_stats();
1597 val = sample->period * evsel->scale;
1598 perf_stat__update_shadow_stats(evsel,
1599 val,
1600 sample->cpu,
1601 &rt_stat);
1602 evsel_script(evsel)->val = val;
1603 if (evsel_script(evsel->leader)->gnum == evsel->leader->nr_members) {
1604 for_each_group_member (ev2, evsel->leader) {
1605 perf_stat__print_shadow_stats(ev2,
1606 evsel_script(ev2)->val,
1607 sample->cpu,
1608 &ctx,
1609 NULL,
1610 &rt_stat);
1611 }
1612 evsel_script(evsel->leader)->gnum = 0;
1613 }
1614}
1615
1480static void process_event(struct perf_script *script, 1616static void process_event(struct perf_script *script,
1481 struct perf_sample *sample, struct perf_evsel *evsel, 1617 struct perf_sample *sample, struct perf_evsel *evsel,
1482 struct addr_location *al, 1618 struct addr_location *al,
@@ -1493,7 +1629,8 @@ static void process_event(struct perf_script *script,
1493 1629
1494 ++es->samples; 1630 ++es->samples;
1495 1631
1496 perf_sample__fprintf_start(sample, thread, evsel, fp); 1632 perf_sample__fprintf_start(sample, thread, evsel,
1633 PERF_RECORD_SAMPLE, fp);
1497 1634
1498 if (PRINT_FIELD(PERIOD)) 1635 if (PRINT_FIELD(PERIOD))
1499 fprintf(fp, "%10" PRIu64 " ", sample->period); 1636 fprintf(fp, "%10" PRIu64 " ", sample->period);
@@ -1564,6 +1701,9 @@ static void process_event(struct perf_script *script,
1564 if (PRINT_FIELD(PHYS_ADDR)) 1701 if (PRINT_FIELD(PHYS_ADDR))
1565 fprintf(fp, "%16" PRIx64, sample->phys_addr); 1702 fprintf(fp, "%16" PRIx64, sample->phys_addr);
1566 fprintf(fp, "\n"); 1703 fprintf(fp, "\n");
1704
1705 if (PRINT_FIELD(METRIC))
1706 perf_sample__fprint_metric(script, thread, evsel, sample, fp);
1567} 1707}
1568 1708
1569static struct scripting_ops *scripting_ops; 1709static struct scripting_ops *scripting_ops;
@@ -1643,8 +1783,10 @@ static int process_sample_event(struct perf_tool *tool,
1643 struct perf_script *scr = container_of(tool, struct perf_script, tool); 1783 struct perf_script *scr = container_of(tool, struct perf_script, tool);
1644 struct addr_location al; 1784 struct addr_location al;
1645 1785
1646 if (perf_time__skip_sample(&scr->ptime, sample->time)) 1786 if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,
1787 sample->time)) {
1647 return 0; 1788 return 0;
1789 }
1648 1790
1649 if (debug_mode) { 1791 if (debug_mode) {
1650 if (sample->time < last_timestamp) { 1792 if (sample->time < last_timestamp) {
@@ -1737,7 +1879,8 @@ static int process_comm_event(struct perf_tool *tool,
1737 sample->tid = event->comm.tid; 1879 sample->tid = event->comm.tid;
1738 sample->pid = event->comm.pid; 1880 sample->pid = event->comm.pid;
1739 } 1881 }
1740 perf_sample__fprintf_start(sample, thread, evsel, stdout); 1882 perf_sample__fprintf_start(sample, thread, evsel,
1883 PERF_RECORD_COMM, stdout);
1741 perf_event__fprintf(event, stdout); 1884 perf_event__fprintf(event, stdout);
1742 ret = 0; 1885 ret = 0;
1743out: 1886out:
@@ -1772,7 +1915,8 @@ static int process_namespaces_event(struct perf_tool *tool,
1772 sample->tid = event->namespaces.tid; 1915 sample->tid = event->namespaces.tid;
1773 sample->pid = event->namespaces.pid; 1916 sample->pid = event->namespaces.pid;
1774 } 1917 }
1775 perf_sample__fprintf_start(sample, thread, evsel, stdout); 1918 perf_sample__fprintf_start(sample, thread, evsel,
1919 PERF_RECORD_NAMESPACES, stdout);
1776 perf_event__fprintf(event, stdout); 1920 perf_event__fprintf(event, stdout);
1777 ret = 0; 1921 ret = 0;
1778out: 1922out:
@@ -1805,7 +1949,8 @@ static int process_fork_event(struct perf_tool *tool,
1805 sample->tid = event->fork.tid; 1949 sample->tid = event->fork.tid;
1806 sample->pid = event->fork.pid; 1950 sample->pid = event->fork.pid;
1807 } 1951 }
1808 perf_sample__fprintf_start(sample, thread, evsel, stdout); 1952 perf_sample__fprintf_start(sample, thread, evsel,
1953 PERF_RECORD_FORK, stdout);
1809 perf_event__fprintf(event, stdout); 1954 perf_event__fprintf(event, stdout);
1810 thread__put(thread); 1955 thread__put(thread);
1811 1956
@@ -1834,7 +1979,8 @@ static int process_exit_event(struct perf_tool *tool,
1834 sample->tid = event->fork.tid; 1979 sample->tid = event->fork.tid;
1835 sample->pid = event->fork.pid; 1980 sample->pid = event->fork.pid;
1836 } 1981 }
1837 perf_sample__fprintf_start(sample, thread, evsel, stdout); 1982 perf_sample__fprintf_start(sample, thread, evsel,
1983 PERF_RECORD_EXIT, stdout);
1838 perf_event__fprintf(event, stdout); 1984 perf_event__fprintf(event, stdout);
1839 1985
1840 if (perf_event__process_exit(tool, event, sample, machine) < 0) 1986 if (perf_event__process_exit(tool, event, sample, machine) < 0)
@@ -1869,7 +2015,8 @@ static int process_mmap_event(struct perf_tool *tool,
1869 sample->tid = event->mmap.tid; 2015 sample->tid = event->mmap.tid;
1870 sample->pid = event->mmap.pid; 2016 sample->pid = event->mmap.pid;
1871 } 2017 }
1872 perf_sample__fprintf_start(sample, thread, evsel, stdout); 2018 perf_sample__fprintf_start(sample, thread, evsel,
2019 PERF_RECORD_MMAP, stdout);
1873 perf_event__fprintf(event, stdout); 2020 perf_event__fprintf(event, stdout);
1874 thread__put(thread); 2021 thread__put(thread);
1875 return 0; 2022 return 0;
@@ -1900,7 +2047,8 @@ static int process_mmap2_event(struct perf_tool *tool,
1900 sample->tid = event->mmap2.tid; 2047 sample->tid = event->mmap2.tid;
1901 sample->pid = event->mmap2.pid; 2048 sample->pid = event->mmap2.pid;
1902 } 2049 }
1903 perf_sample__fprintf_start(sample, thread, evsel, stdout); 2050 perf_sample__fprintf_start(sample, thread, evsel,
2051 PERF_RECORD_MMAP2, stdout);
1904 perf_event__fprintf(event, stdout); 2052 perf_event__fprintf(event, stdout);
1905 thread__put(thread); 2053 thread__put(thread);
1906 return 0; 2054 return 0;
@@ -1926,7 +2074,31 @@ static int process_switch_event(struct perf_tool *tool,
1926 return -1; 2074 return -1;
1927 } 2075 }
1928 2076
1929 perf_sample__fprintf_start(sample, thread, evsel, stdout); 2077 perf_sample__fprintf_start(sample, thread, evsel,
2078 PERF_RECORD_SWITCH, stdout);
2079 perf_event__fprintf(event, stdout);
2080 thread__put(thread);
2081 return 0;
2082}
2083
2084static int
2085process_lost_event(struct perf_tool *tool,
2086 union perf_event *event,
2087 struct perf_sample *sample,
2088 struct machine *machine)
2089{
2090 struct perf_script *script = container_of(tool, struct perf_script, tool);
2091 struct perf_session *session = script->session;
2092 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2093 struct thread *thread;
2094
2095 thread = machine__findnew_thread(machine, sample->pid,
2096 sample->tid);
2097 if (thread == NULL)
2098 return -1;
2099
2100 perf_sample__fprintf_start(sample, thread, evsel,
2101 PERF_RECORD_LOST, stdout);
1930 perf_event__fprintf(event, stdout); 2102 perf_event__fprintf(event, stdout);
1931 thread__put(thread); 2103 thread__put(thread);
1932 return 0; 2104 return 0;
@@ -2026,6 +2198,8 @@ static int __cmd_script(struct perf_script *script)
2026 script->tool.context_switch = process_switch_event; 2198 script->tool.context_switch = process_switch_event;
2027 if (script->show_namespace_events) 2199 if (script->show_namespace_events)
2028 script->tool.namespaces = process_namespaces_event; 2200 script->tool.namespaces = process_namespaces_event;
2201 if (script->show_lost_events)
2202 script->tool.lost = process_lost_event;
2029 2203
2030 if (perf_script__setup_per_event_dump(script)) { 2204 if (perf_script__setup_per_event_dump(script)) {
2031 pr_err("Couldn't create the per event dump files\n"); 2205 pr_err("Couldn't create the per event dump files\n");
@@ -2311,19 +2485,6 @@ out:
2311 return rc; 2485 return rc;
2312} 2486}
2313 2487
2314/* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */
2315static int is_directory(const char *base_path, const struct dirent *dent)
2316{
2317 char path[PATH_MAX];
2318 struct stat st;
2319
2320 sprintf(path, "%s/%s", base_path, dent->d_name);
2321 if (stat(path, &st))
2322 return 0;
2323
2324 return S_ISDIR(st.st_mode);
2325}
2326
2327#define for_each_lang(scripts_path, scripts_dir, lang_dirent) \ 2488#define for_each_lang(scripts_path, scripts_dir, lang_dirent) \
2328 while ((lang_dirent = readdir(scripts_dir)) != NULL) \ 2489 while ((lang_dirent = readdir(scripts_dir)) != NULL) \
2329 if ((lang_dirent->d_type == DT_DIR || \ 2490 if ((lang_dirent->d_type == DT_DIR || \
@@ -2758,9 +2919,10 @@ static void script__setup_sample_type(struct perf_script *script)
2758 2919
2759 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) { 2920 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
2760 if ((sample_type & PERF_SAMPLE_REGS_USER) && 2921 if ((sample_type & PERF_SAMPLE_REGS_USER) &&
2761 (sample_type & PERF_SAMPLE_STACK_USER)) 2922 (sample_type & PERF_SAMPLE_STACK_USER)) {
2762 callchain_param.record_mode = CALLCHAIN_DWARF; 2923 callchain_param.record_mode = CALLCHAIN_DWARF;
2763 else if (sample_type & PERF_SAMPLE_BRANCH_STACK) 2924 dwarf_callchain_users = true;
2925 } else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
2764 callchain_param.record_mode = CALLCHAIN_LBR; 2926 callchain_param.record_mode = CALLCHAIN_LBR;
2765 else 2927 else
2766 callchain_param.record_mode = CALLCHAIN_FP; 2928 callchain_param.record_mode = CALLCHAIN_FP;
@@ -2975,6 +3137,8 @@ int cmd_script(int argc, const char **argv)
2975 "Show context switch events (if recorded)"), 3137 "Show context switch events (if recorded)"),
2976 OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events, 3138 OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
2977 "Show namespace events (if recorded)"), 3139 "Show namespace events (if recorded)"),
3140 OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events,
3141 "Show lost events (if recorded)"),
2978 OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump, 3142 OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
2979 "Dump trace output to files named by the monitored events"), 3143 "Dump trace output to files named by the monitored events"),
2980 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), 3144 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
@@ -3281,18 +3445,46 @@ int cmd_script(int argc, const char **argv)
3281 if (err < 0) 3445 if (err < 0)
3282 goto out_delete; 3446 goto out_delete;
3283 3447
3284 /* needs to be parsed after looking up reference time */ 3448 script.ptime_range = perf_time__range_alloc(script.time_str,
3285 if (perf_time__parse_str(&script.ptime, script.time_str) != 0) { 3449 &script.range_size);
3286 pr_err("Invalid time string\n"); 3450 if (!script.ptime_range) {
3287 err = -EINVAL; 3451 err = -ENOMEM;
3288 goto out_delete; 3452 goto out_delete;
3289 } 3453 }
3290 3454
3455 /* needs to be parsed after looking up reference time */
3456 if (perf_time__parse_str(script.ptime_range, script.time_str) != 0) {
3457 if (session->evlist->first_sample_time == 0 &&
3458 session->evlist->last_sample_time == 0) {
3459 pr_err("HINT: no first/last sample time found in perf data.\n"
3460 "Please use latest perf binary to execute 'perf record'\n"
3461 "(if '--buildid-all' is enabled, please set '--timestamp-boundary').\n");
3462 err = -EINVAL;
3463 goto out_delete;
3464 }
3465
3466 script.range_num = perf_time__percent_parse_str(
3467 script.ptime_range, script.range_size,
3468 script.time_str,
3469 session->evlist->first_sample_time,
3470 session->evlist->last_sample_time);
3471
3472 if (script.range_num < 0) {
3473 pr_err("Invalid time string\n");
3474 err = -EINVAL;
3475 goto out_delete;
3476 }
3477 } else {
3478 script.range_num = 1;
3479 }
3480
3291 err = __cmd_script(&script); 3481 err = __cmd_script(&script);
3292 3482
3293 flush_scripting(); 3483 flush_scripting();
3294 3484
3295out_delete: 3485out_delete:
3486 zfree(&script.ptime_range);
3487
3296 perf_evlist__free_stats(session->evlist); 3488 perf_evlist__free_stats(session->evlist);
3297 perf_session__delete(session); 3489 perf_session__delete(session);
3298 3490