diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 12:30:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 12:30:52 -0400 |
commit | 4aed2fd8e3181fea7c09ba79cf64e7e3f4413bf9 (patch) | |
tree | 1f69733e5daab4915a76a41de0e4d1dc61e12cfb /tools/perf/util/session.c | |
parent | 3a3527b6461b1298cc53ce72f336346739297ac8 (diff) | |
parent | fc9ea5a1e53ee54f681e226d735008e2a6f8f470 (diff) |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (162 commits)
tracing/kprobes: unregister_trace_probe needs to be called under mutex
perf: expose event__process function
perf events: Fix mmap offset determination
perf, powerpc: fsl_emb: Restore setting perf_sample_data.period
perf, powerpc: Convert the FSL driver to use local64_t
perf tools: Don't keep unreferenced maps when unmaps are detected
perf session: Invalidate last_match when removing threads from rb_tree
perf session: Free the ref_reloc_sym memory at the right place
x86,mmiotrace: Add support for tracing STOS instruction
perf, sched migration: Librarize task states and event headers helpers
perf, sched migration: Librarize the GUI class
perf, sched migration: Make the GUI class client agnostic
perf, sched migration: Make it vertically scrollable
perf, sched migration: Parameterize cpu height and spacing
perf, sched migration: Fix key bindings
perf, sched migration: Ignore unhandled task states
perf, sched migration: Handle ignored migrate out events
perf: New migration tool overview
tracing: Drop cpparg() macro
perf: Use tracepoint_synchronize_unregister() to flush any pending tracepoint call
...
Fix up trivial conflicts in Makefile and drivers/cpufreq/cpufreq.c
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r-- | tools/perf/util/session.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index c422cd676313..fa9d652c2dc3 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -27,8 +27,10 @@ static int perf_session__open(struct perf_session *self, bool force) | |||
27 | 27 | ||
28 | self->fd = open(self->filename, O_RDONLY); | 28 | self->fd = open(self->filename, O_RDONLY); |
29 | if (self->fd < 0) { | 29 | if (self->fd < 0) { |
30 | pr_err("failed to open file: %s", self->filename); | 30 | int err = errno; |
31 | if (!strcmp(self->filename, "perf.data")) | 31 | |
32 | pr_err("failed to open %s: %s", self->filename, strerror(err)); | ||
33 | if (err == ENOENT && !strcmp(self->filename, "perf.data")) | ||
32 | pr_err(" (try 'perf record' first)"); | 34 | pr_err(" (try 'perf record' first)"); |
33 | pr_err("\n"); | 35 | pr_err("\n"); |
34 | return -errno; | 36 | return -errno; |
@@ -77,6 +79,12 @@ int perf_session__create_kernel_maps(struct perf_session *self) | |||
77 | return ret; | 79 | return ret; |
78 | } | 80 | } |
79 | 81 | ||
82 | static void perf_session__destroy_kernel_maps(struct perf_session *self) | ||
83 | { | ||
84 | machine__destroy_kernel_maps(&self->host_machine); | ||
85 | machines__destroy_guest_kernel_maps(&self->machines); | ||
86 | } | ||
87 | |||
80 | struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) | 88 | struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) |
81 | { | 89 | { |
82 | size_t len = filename ? strlen(filename) + 1 : 0; | 90 | size_t len = filename ? strlen(filename) + 1 : 0; |
@@ -94,8 +102,6 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc | |||
94 | self->hists_tree = RB_ROOT; | 102 | self->hists_tree = RB_ROOT; |
95 | self->last_match = NULL; | 103 | self->last_match = NULL; |
96 | self->mmap_window = 32; | 104 | self->mmap_window = 32; |
97 | self->cwd = NULL; | ||
98 | self->cwdlen = 0; | ||
99 | self->machines = RB_ROOT; | 105 | self->machines = RB_ROOT; |
100 | self->repipe = repipe; | 106 | self->repipe = repipe; |
101 | INIT_LIST_HEAD(&self->ordered_samples.samples_head); | 107 | INIT_LIST_HEAD(&self->ordered_samples.samples_head); |
@@ -124,16 +130,43 @@ out_delete: | |||
124 | return NULL; | 130 | return NULL; |
125 | } | 131 | } |
126 | 132 | ||
133 | static void perf_session__delete_dead_threads(struct perf_session *self) | ||
134 | { | ||
135 | struct thread *n, *t; | ||
136 | |||
137 | list_for_each_entry_safe(t, n, &self->dead_threads, node) { | ||
138 | list_del(&t->node); | ||
139 | thread__delete(t); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static void perf_session__delete_threads(struct perf_session *self) | ||
144 | { | ||
145 | struct rb_node *nd = rb_first(&self->threads); | ||
146 | |||
147 | while (nd) { | ||
148 | struct thread *t = rb_entry(nd, struct thread, rb_node); | ||
149 | |||
150 | rb_erase(&t->rb_node, &self->threads); | ||
151 | nd = rb_next(nd); | ||
152 | thread__delete(t); | ||
153 | } | ||
154 | } | ||
155 | |||
127 | void perf_session__delete(struct perf_session *self) | 156 | void perf_session__delete(struct perf_session *self) |
128 | { | 157 | { |
129 | perf_header__exit(&self->header); | 158 | perf_header__exit(&self->header); |
159 | perf_session__destroy_kernel_maps(self); | ||
160 | perf_session__delete_dead_threads(self); | ||
161 | perf_session__delete_threads(self); | ||
162 | machine__exit(&self->host_machine); | ||
130 | close(self->fd); | 163 | close(self->fd); |
131 | free(self->cwd); | ||
132 | free(self); | 164 | free(self); |
133 | } | 165 | } |
134 | 166 | ||
135 | void perf_session__remove_thread(struct perf_session *self, struct thread *th) | 167 | void perf_session__remove_thread(struct perf_session *self, struct thread *th) |
136 | { | 168 | { |
169 | self->last_match = NULL; | ||
137 | rb_erase(&th->rb_node, &self->threads); | 170 | rb_erase(&th->rb_node, &self->threads); |
138 | /* | 171 | /* |
139 | * We may have references to this thread, for instance in some hist_entry | 172 | * We may have references to this thread, for instance in some hist_entry |
@@ -830,23 +863,6 @@ int perf_session__process_events(struct perf_session *self, | |||
830 | if (perf_session__register_idle_thread(self) == NULL) | 863 | if (perf_session__register_idle_thread(self) == NULL) |
831 | return -ENOMEM; | 864 | return -ENOMEM; |
832 | 865 | ||
833 | if (!symbol_conf.full_paths) { | ||
834 | char bf[PATH_MAX]; | ||
835 | |||
836 | if (getcwd(bf, sizeof(bf)) == NULL) { | ||
837 | err = -errno; | ||
838 | out_getcwd_err: | ||
839 | pr_err("failed to get the current directory\n"); | ||
840 | goto out_err; | ||
841 | } | ||
842 | self->cwd = strdup(bf); | ||
843 | if (self->cwd == NULL) { | ||
844 | err = -ENOMEM; | ||
845 | goto out_getcwd_err; | ||
846 | } | ||
847 | self->cwdlen = strlen(self->cwd); | ||
848 | } | ||
849 | |||
850 | if (!self->fd_pipe) | 866 | if (!self->fd_pipe) |
851 | err = __perf_session__process_events(self, | 867 | err = __perf_session__process_events(self, |
852 | self->header.data_offset, | 868 | self->header.data_offset, |
@@ -854,7 +870,7 @@ out_getcwd_err: | |||
854 | self->size, ops); | 870 | self->size, ops); |
855 | else | 871 | else |
856 | err = __perf_session__process_pipe_events(self, ops); | 872 | err = __perf_session__process_pipe_events(self, ops); |
857 | out_err: | 873 | |
858 | return err; | 874 | return err; |
859 | } | 875 | } |
860 | 876 | ||