aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-sched.c
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-10-07 06:47:31 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-08 10:56:32 -0400
commit016e92fbc9ef33689cf654f343a94383d43235e7 (patch)
treeedf9dc21d037ea138300b7e7e32574e6f6f17fb2 /tools/perf/builtin-sched.c
parent03456a158d9067d2f657bec170506009db81756d (diff)
perf tools: Unify perf.data mapping and events handling
This librarizes the perf.data file mapping and handling in various perf tools, roughly reducing the amount of code and fixing the places that mmap from beginning of the file whereas we want to mmap from the beginning of the data, leading to page fault because the mmap window is too small since the trace info are written in the file too. TODO: - convert perf timechart too Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Arjan van de Ven <arjan@infradead.org> LKML-Reference: <20091007104729.GD5043@nowhere> Signed-off-by: Ingo Molnar <mingo@elte.hu>
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);