Commit 5904b3b8 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'perf-fixes-for-linus' of...

Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  tracing: Fix undeclared ENOSYS in include/linux/tracepoint.h
  perf record: prevent kill(0, SIGTERM);
  perf session: Remove threads from tree on PERF_RECORD_EXIT
  perf/tracing: Fix regression of perf losing kprobe events
  perf_events: Fix Intel Westmere event constraints
  perf record: Don't call newt functions when not initialized
parents f3866db8 b70e4f05
...@@ -72,6 +72,7 @@ static struct event_constraint intel_westmere_event_constraints[] = ...@@ -72,6 +72,7 @@ static struct event_constraint intel_westmere_event_constraints[] =
INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */ INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */ INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */
INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */ INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
INTEL_EVENT_CONSTRAINT(0xb3, 0x1), /* SNOOPQ_REQUEST_OUTSTANDING */
EVENT_CONSTRAINT_END EVENT_CONSTRAINT_END
}; };
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* See the file COPYING for more details. * See the file COPYING for more details.
*/ */
#include <linux/errno.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
......
...@@ -96,7 +96,9 @@ int perf_trace_init(struct perf_event *p_event) ...@@ -96,7 +96,9 @@ int perf_trace_init(struct perf_event *p_event)
mutex_lock(&event_mutex); mutex_lock(&event_mutex);
list_for_each_entry(tp_event, &ftrace_events, list) { list_for_each_entry(tp_event, &ftrace_events, list) {
if (tp_event->event.type == event_id && if (tp_event->event.type == event_id &&
tp_event->class && tp_event->class->perf_probe && tp_event->class &&
(tp_event->class->perf_probe ||
tp_event->class->reg) &&
try_module_get(tp_event->mod)) { try_module_get(tp_event->mod)) {
ret = perf_trace_event_init(tp_event, p_event); ret = perf_trace_event_init(tp_event, p_event);
break; break;
......
...@@ -193,7 +193,7 @@ static void sig_handler(int sig) ...@@ -193,7 +193,7 @@ static void sig_handler(int sig)
static void sig_atexit(void) static void sig_atexit(void)
{ {
if (child_pid != -1) if (child_pid > 0)
kill(child_pid, SIGTERM); kill(child_pid, SIGTERM);
if (signr == -1) if (signr == -1)
......
...@@ -538,8 +538,10 @@ int event__process_task(event_t *self, struct perf_session *session) ...@@ -538,8 +538,10 @@ int event__process_task(event_t *self, struct perf_session *session)
dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid, dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid,
self->fork.ppid, self->fork.ptid); self->fork.ppid, self->fork.ptid);
if (self->header.type == PERF_RECORD_EXIT) if (self->header.type == PERF_RECORD_EXIT) {
perf_session__remove_thread(session, thread);
return 0; return 0;
}
if (thread == NULL || parent == NULL || if (thread == NULL || parent == NULL ||
thread__fork(thread, parent) < 0) { thread__fork(thread, parent) < 0) {
......
...@@ -43,6 +43,9 @@ struct ui_progress *ui_progress__new(const char *title, u64 total) ...@@ -43,6 +43,9 @@ struct ui_progress *ui_progress__new(const char *title, u64 total)
if (self != NULL) { if (self != NULL) {
int cols; int cols;
if (use_browser <= 0)
return self;
newtGetScreenSize(&cols, NULL); newtGetScreenSize(&cols, NULL);
cols -= 4; cols -= 4;
newtCenteredWindow(cols, 1, title); newtCenteredWindow(cols, 1, title);
...@@ -67,14 +70,22 @@ struct ui_progress *ui_progress__new(const char *title, u64 total) ...@@ -67,14 +70,22 @@ struct ui_progress *ui_progress__new(const char *title, u64 total)
void ui_progress__update(struct ui_progress *self, u64 curr) void ui_progress__update(struct ui_progress *self, u64 curr)
{ {
/*
* FIXME: We should have a per UI backend way of showing progress,
* stdio will just show a percentage as NN%, etc.
*/
if (use_browser <= 0)
return;
newtScaleSet(self->scale, curr); newtScaleSet(self->scale, curr);
newtRefresh(); newtRefresh();
} }
void ui_progress__delete(struct ui_progress *self) void ui_progress__delete(struct ui_progress *self)
{ {
newtFormDestroy(self->form); if (use_browser > 0) {
newtPopWindow(); newtFormDestroy(self->form);
newtPopWindow();
}
free(self); free(self);
} }
......
...@@ -90,6 +90,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc ...@@ -90,6 +90,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
memcpy(self->filename, filename, len); memcpy(self->filename, filename, len);
self->threads = RB_ROOT; self->threads = RB_ROOT;
INIT_LIST_HEAD(&self->dead_threads);
self->hists_tree = RB_ROOT; self->hists_tree = RB_ROOT;
self->last_match = NULL; self->last_match = NULL;
self->mmap_window = 32; self->mmap_window = 32;
...@@ -131,6 +132,16 @@ void perf_session__delete(struct perf_session *self) ...@@ -131,6 +132,16 @@ void perf_session__delete(struct perf_session *self)
free(self); free(self);
} }
void perf_session__remove_thread(struct perf_session *self, struct thread *th)
{
rb_erase(&th->rb_node, &self->threads);
/*
* We may have references to this thread, for instance in some hist_entry
* instances, so just move them to a separate list.
*/
list_add_tail(&th->node, &self->dead_threads);
}
static bool symbol__match_parent_regex(struct symbol *sym) static bool symbol__match_parent_regex(struct symbol *sym)
{ {
if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0)) if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
......
...@@ -26,6 +26,7 @@ struct perf_session { ...@@ -26,6 +26,7 @@ struct perf_session {
unsigned long size; unsigned long size;
unsigned long mmap_window; unsigned long mmap_window;
struct rb_root threads; struct rb_root threads;
struct list_head dead_threads;
struct thread *last_match; struct thread *last_match;
struct machine host_machine; struct machine host_machine;
struct rb_root machines; struct rb_root machines;
...@@ -99,6 +100,7 @@ int perf_session__create_kernel_maps(struct perf_session *self); ...@@ -99,6 +100,7 @@ int perf_session__create_kernel_maps(struct perf_session *self);
int do_read(int fd, void *buf, size_t size); int do_read(int fd, void *buf, size_t size);
void perf_session__update_sample_type(struct perf_session *self); void perf_session__update_sample_type(struct perf_session *self);
void perf_session__remove_thread(struct perf_session *self, struct thread *th);
static inline static inline
struct machine *perf_session__find_host_machine(struct perf_session *self) struct machine *perf_session__find_host_machine(struct perf_session *self)
......
...@@ -6,7 +6,10 @@ ...@@ -6,7 +6,10 @@
#include "symbol.h" #include "symbol.h"
struct thread { struct thread {
struct rb_node rb_node; union {
struct rb_node rb_node;
struct list_head node;
};
struct map_groups mg; struct map_groups mg;
pid_t pid; pid_t pid;
char shortname[3]; char shortname[3];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment