Skip to content

Commit

Permalink
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/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:
  perf probe: Init struct probe_point and set counter correctly
  hw-breakpoint: Keep track of dr7 local enable bits
  hw-breakpoints: Accept breakpoints on NULL address
  perf_events: Fix FORK events
  • Loading branch information
Linus Torvalds committed Feb 22, 2010
2 parents 627fa17 + 388c3aa commit bee415c
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 31 deletions.
2 changes: 2 additions & 0 deletions arch/x86/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ struct thread_struct {
struct perf_event *ptrace_bps[HBP_NUM];
/* Debug status used for traps, single steps, etc... */
unsigned long debugreg6;
/* Keep track of the exact dr7 value set by the user */
unsigned long ptrace_dr7;
/* Fault info: */
unsigned long cr2;
unsigned long trap_no;
Expand Down
30 changes: 7 additions & 23 deletions arch/x86/kernel/hw_breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,25 +212,6 @@ static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
}

/*
* Store a breakpoint's encoded address, length, and type.
*/
static int arch_store_info(struct perf_event *bp)
{
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
/*
* For kernel-addresses, either the address or symbol name can be
* specified.
*/
if (info->name)
info->address = (unsigned long)
kallsyms_lookup_name(info->name);
if (info->address)
return 0;

return -EINVAL;
}

int arch_bp_generic_fields(int x86_len, int x86_type,
int *gen_len, int *gen_type)
{
Expand Down Expand Up @@ -362,10 +343,13 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
return ret;
}

ret = arch_store_info(bp);

if (ret < 0)
return ret;
/*
* For kernel-addresses, either the address or symbol name can be
* specified.
*/
if (info->name)
info->address = (unsigned long)
kallsyms_lookup_name(info->name);
/*
* Check that the low-order bits of the address are appropriate
* for the alignment implied by len.
Expand Down
7 changes: 5 additions & 2 deletions arch/x86/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n)
} else if (n == 6) {
val = thread->debugreg6;
} else if (n == 7) {
val = ptrace_get_dr7(thread->ptrace_bps);
val = thread->ptrace_dr7;
}
return val;
}
Expand Down Expand Up @@ -778,8 +778,11 @@ int ptrace_set_debugreg(struct task_struct *tsk, int n, unsigned long val)
return rc;
}
/* All that's left is DR7 */
if (n == 7)
if (n == 7) {
rc = ptrace_write_dr7(tsk, val);
if (!rc)
thread->ptrace_dr7 = val;
}

ret_path:
return rc;
Expand Down
11 changes: 5 additions & 6 deletions kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -3259,16 +3259,14 @@ static void perf_event_task_output(struct perf_event *event,
task_event->event_id.tid = perf_event_tid(event, task);
task_event->event_id.ptid = perf_event_tid(event, current);

task_event->event_id.time = perf_clock();

perf_output_put(&handle, task_event->event_id);

perf_output_end(&handle);
}

static int perf_event_task_match(struct perf_event *event)
{
if (event->state != PERF_EVENT_STATE_ACTIVE)
if (event->state < PERF_EVENT_STATE_INACTIVE)
return 0;

if (event->cpu != -1 && event->cpu != smp_processor_id())
Expand Down Expand Up @@ -3300,7 +3298,7 @@ static void perf_event_task_event(struct perf_task_event *task_event)
cpuctx = &get_cpu_var(perf_cpu_context);
perf_event_task_ctx(&cpuctx->ctx, task_event);
if (!ctx)
ctx = rcu_dereference(task_event->task->perf_event_ctxp);
ctx = rcu_dereference(current->perf_event_ctxp);
if (ctx)
perf_event_task_ctx(ctx, task_event);
put_cpu_var(perf_cpu_context);
Expand Down Expand Up @@ -3331,6 +3329,7 @@ static void perf_event_task(struct task_struct *task,
/* .ppid */
/* .tid */
/* .ptid */
.time = perf_clock(),
},
};

Expand Down Expand Up @@ -3380,7 +3379,7 @@ static void perf_event_comm_output(struct perf_event *event,

static int perf_event_comm_match(struct perf_event *event)
{
if (event->state != PERF_EVENT_STATE_ACTIVE)
if (event->state < PERF_EVENT_STATE_INACTIVE)
return 0;

if (event->cpu != -1 && event->cpu != smp_processor_id())
Expand Down Expand Up @@ -3500,7 +3499,7 @@ static void perf_event_mmap_output(struct perf_event *event,
static int perf_event_mmap_match(struct perf_event *event,
struct perf_mmap_event *mmap_event)
{
if (event->state != PERF_EVENT_STATE_ACTIVE)
if (event->state < PERF_EVENT_STATE_INACTIVE)
return 0;

if (event->cpu != -1 && event->cpu != smp_processor_id())
Expand Down
3 changes: 3 additions & 0 deletions tools/perf/util/probe-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ int synthesize_perf_probe_point(struct probe_point *pp)
int ret;

pp->probes[0] = buf = zalloc(MAX_CMDLEN);
pp->found = 1;
if (!buf)
die("Failed to allocate memory by zalloc.");
if (pp->offset) {
Expand All @@ -294,6 +295,7 @@ int synthesize_perf_probe_point(struct probe_point *pp)
error:
free(pp->probes[0]);
pp->probes[0] = NULL;
pp->found = 0;
}
return ret;
}
Expand Down Expand Up @@ -455,6 +457,7 @@ void show_perf_probe_events(void)
struct strlist *rawlist;
struct str_node *ent;

memset(&pp, 0, sizeof(pp));
fd = open_kprobe_events(O_RDONLY, 0);
rawlist = get_trace_kprobe_event_rawlist(fd);
close(fd);
Expand Down

0 comments on commit bee415c

Please sign in to comment.