aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-sched.c')
-rw-r--r--tools/perf/builtin-sched.c140
1 files changed, 27 insertions, 113 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 18871380b015..e1df7055ab82 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -11,6 +11,7 @@
11#include "util/trace-event.h" 11#include "util/trace-event.h"
12 12
13#include "util/debug.h" 13#include "util/debug.h"
14#include "util/data_map.h"
14 15
15#include <sys/types.h> 16#include <sys/types.h>
16#include <sys/prctl.h> 17#include <sys/prctl.h>
@@ -20,9 +21,6 @@
20#include <math.h> 21#include <math.h>
21 22
22static char const *input_name = "perf.data"; 23static char const *input_name = "perf.data";
23static int input;
24static unsigned long page_size;
25static unsigned long mmap_window = 32;
26 24
27static unsigned long total_comm = 0; 25static unsigned long total_comm = 0;
28 26
@@ -35,6 +33,9 @@ static u64 sample_type;
35static char default_sort_order[] = "avg, max, switch, runtime"; 33static char default_sort_order[] = "avg, max, switch, runtime";
36static char *sort_order = default_sort_order; 34static char *sort_order = default_sort_order;
37 35
36static char *cwd;
37static int cwdlen;
38
38#define PR_SET_NAME 15 /* Set process name */ 39#define PR_SET_NAME 15 /* Set process name */
39#define MAX_CPUS 4096 40#define MAX_CPUS 4096
40 41
@@ -1594,129 +1595,43 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1594} 1595}
1595 1596
1596static int 1597static int
1597process_event(event_t *event, unsigned long offset, unsigned long head) 1598process_lost_event(event_t *event __used,
1599 unsigned long offset __used,
1600 unsigned long head __used)
1598{ 1601{
1599 trace_event(event); 1602 nr_lost_chunks++;
1600 1603 nr_lost_events += event->lost.lost;
1601 nr_events++;
1602 switch (event->header.type) {
1603 case PERF_RECORD_MMAP:
1604 return 0;
1605 case PERF_RECORD_LOST:
1606 nr_lost_chunks++;
1607 nr_lost_events += event->lost.lost;
1608 return 0;
1609
1610 case PERF_RECORD_COMM:
1611 return process_comm_event(event, offset, head);
1612 1604
1613 case PERF_RECORD_EXIT ... PERF_RECORD_READ: 1605 return 0;
1614 return 0; 1606}
1615 1607
1616 case PERF_RECORD_SAMPLE: 1608static int sample_type_check(u64 type)
1617 return process_sample_event(event, offset, head); 1609{
1610 sample_type = type;
1618 1611
1619 case PERF_RECORD_MAX: 1612 if (!(sample_type & PERF_SAMPLE_RAW)) {
1620 default: 1613 fprintf(stderr,
1614 "No trace sample to read. Did you call perf record "
1615 "without -R?");
1621 return -1; 1616 return -1;
1622 } 1617 }
1623 1618
1624 return 0; 1619 return 0;
1625} 1620}
1626 1621
1622static struct perf_file_handler file_handler = {
1623 .process_sample_event = process_sample_event,
1624 .process_comm_event = process_comm_event,
1625 .process_lost_event = process_lost_event,
1626 .sample_type_check = sample_type_check,
1627};
1628
1627static int read_events(void) 1629static int read_events(void)
1628{ 1630{
1629 int ret, rc = EXIT_FAILURE;
1630 unsigned long offset = 0;
1631 unsigned long head = 0;
1632 struct stat perf_stat;
1633 event_t *event;
1634 uint32_t size;
1635 char *buf;
1636
1637 register_idle_thread(&threads, &last_match); 1631 register_idle_thread(&threads, &last_match);
1632 register_perf_file_handler(&file_handler);
1638 1633
1639 input = open(input_name, O_RDONLY); 1634 return mmap_dispatch_perf_file(&header, input_name, 0, 0, &cwdlen, &cwd);
1640 if (input < 0) {
1641 perror("failed to open file");
1642 exit(-1);
1643 }
1644
1645 ret = fstat(input, &perf_stat);
1646 if (ret < 0) {
1647 perror("failed to stat file");
1648 exit(-1);
1649 }
1650
1651 if (!perf_stat.st_size) {
1652 fprintf(stderr, "zero-sized file, nothing to do!\n");
1653 exit(0);
1654 }
1655 header = perf_header__read(input);
1656 head = header->data_offset;
1657 sample_type = perf_header__sample_type(header);
1658
1659 if (!(sample_type & PERF_SAMPLE_RAW))
1660 die("No trace sample to read. Did you call perf record "
1661 "without -R?");
1662
1663 if (load_kernel() < 0) {
1664 perror("failed to load kernel symbols");
1665 return EXIT_FAILURE;
1666 }
1667
1668remap:
1669 buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
1670 MAP_SHARED, input, offset);
1671 if (buf == MAP_FAILED) {
1672 perror("failed to mmap file");
1673 exit(-1);
1674 }
1675
1676more:
1677 event = (event_t *)(buf + head);
1678
1679 size = event->header.size;
1680 if (!size)
1681 size = 8;
1682
1683 if (head + event->header.size >= page_size * mmap_window) {
1684 unsigned long shift = page_size * (head / page_size);
1685 int res;
1686
1687 res = munmap(buf, page_size * mmap_window);
1688 assert(res == 0);
1689
1690 offset += shift;
1691 head -= shift;
1692 goto remap;
1693 }
1694
1695 size = event->header.size;
1696
1697
1698 if (!size || process_event(event, offset, head) < 0) {
1699
1700 /*
1701 * assume we lost track of the stream, check alignment, and
1702 * increment a single u64 in the hope to catch on again 'soon'.
1703 */
1704
1705 if (unlikely(head & 7))
1706 head &= ~7ULL;
1707
1708 size = 8;
1709 }
1710
1711 head += size;
1712
1713 if (offset + head < (unsigned long)perf_stat.st_size)
1714 goto more;
1715
1716 rc = EXIT_SUCCESS;
1717 close(input);
1718
1719 return rc;
1720} 1635}
1721 1636
1722static void print_bad_events(void) 1637static void print_bad_events(void)
@@ -1934,7 +1849,6 @@ static int __cmd_record(int argc, const char **argv)
1934int cmd_sched(int argc, const char **argv, const char *prefix __used) 1849int cmd_sched(int argc, const char **argv, const char *prefix __used)
1935{ 1850{
1936 symbol__init(); 1851 symbol__init();
1937 page_size = getpagesize();
1938 1852
1939 argc = parse_options(argc, argv, sched_options, sched_usage, 1853 argc = parse_options(argc, argv, sched_options, sched_usage,
1940 PARSE_OPT_STOP_AT_NON_OPTION); 1854 PARSE_OPT_STOP_AT_NON_OPTION);