Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 211941
b: refs/heads/master
c: d580ff8
h: refs/heads/master
i:
  211939: ad673e8
v: v3
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Oct 18, 2010
1 parent 7c578e9 commit fd80b10
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c6be5a5cb62592d9d661899a2aa78236eb00ffa5
refs/heads/master: d580ff8699e8811a9af37e9de4dea375401bdeec
7 changes: 7 additions & 0 deletions trunk/include/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,12 @@ struct hw_perf_event {
struct { /* breakpoint */
struct arch_hw_breakpoint info;
struct list_head bp_list;
/*
* Crufty hack to avoid the chicken and egg
* problem hw_breakpoint has with context
* creation and event initalization.
*/
struct task_struct *bp_target;
};
#endif
};
Expand Down Expand Up @@ -693,6 +699,7 @@ struct swevent_hlist {

#define PERF_ATTACH_CONTEXT 0x01
#define PERF_ATTACH_GROUP 0x02
#define PERF_ATTACH_TASK 0x04

/**
* struct perf_event - performance event kernel representation:
Expand Down
8 changes: 4 additions & 4 deletions trunk/kernel/hw_breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type)
*/
static int task_bp_pinned(struct perf_event *bp, enum bp_type_idx type)
{
struct perf_event_context *ctx = bp->ctx;
struct task_struct *tsk = bp->hw.bp_target;
struct perf_event *iter;
int count = 0;

list_for_each_entry(iter, &bp_task_head, hw.bp_list) {
if (iter->ctx == ctx && find_slot_idx(iter) == type)
if (iter->hw.bp_target == tsk && find_slot_idx(iter) == type)
count += hw_breakpoint_weight(iter);
}

Expand All @@ -134,7 +134,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
enum bp_type_idx type)
{
int cpu = bp->cpu;
struct task_struct *tsk = bp->ctx->task;
struct task_struct *tsk = bp->hw.bp_target;

if (cpu >= 0) {
slots->pinned = per_cpu(nr_cpu_bp_pinned[type], cpu);
Expand Down Expand Up @@ -213,7 +213,7 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type,
int weight)
{
int cpu = bp->cpu;
struct task_struct *tsk = bp->ctx->task;
struct task_struct *tsk = bp->hw.bp_target;

/* Pinned counter cpu profiling */
if (!tsk) {
Expand Down
23 changes: 18 additions & 5 deletions trunk/kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -5255,9 +5255,10 @@ struct pmu *perf_init_event(struct perf_event *event)
*/
static struct perf_event *
perf_event_alloc(struct perf_event_attr *attr, int cpu,
struct perf_event *group_leader,
struct perf_event *parent_event,
perf_overflow_handler_t overflow_handler)
struct task_struct *task,
struct perf_event *group_leader,
struct perf_event *parent_event,
perf_overflow_handler_t overflow_handler)
{
struct pmu *pmu;
struct perf_event *event;
Expand Down Expand Up @@ -5299,6 +5300,17 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,

event->state = PERF_EVENT_STATE_INACTIVE;

if (task) {
event->attach_state = PERF_ATTACH_TASK;
#ifdef CONFIG_HAVE_HW_BREAKPOINT
/*
* hw_breakpoint is a bit difficult here..
*/
if (attr->type == PERF_TYPE_BREAKPOINT)
event->hw.bp_target = task;
#endif
}

if (!overflow_handler && parent_event)
overflow_handler = parent_event->overflow_handler;

Expand Down Expand Up @@ -5559,7 +5571,7 @@ SYSCALL_DEFINE5(perf_event_open,
}
}

event = perf_event_alloc(&attr, cpu, group_leader, NULL, NULL);
event = perf_event_alloc(&attr, cpu, task, group_leader, NULL, NULL);
if (IS_ERR(event)) {
err = PTR_ERR(event);
goto err_task;
Expand Down Expand Up @@ -5728,7 +5740,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
* Get the target context (task or percpu):
*/

event = perf_event_alloc(attr, cpu, NULL, NULL, overflow_handler);
event = perf_event_alloc(attr, cpu, task, NULL, NULL, overflow_handler);
if (IS_ERR(event)) {
err = PTR_ERR(event);
goto err;
Expand Down Expand Up @@ -5996,6 +6008,7 @@ inherit_event(struct perf_event *parent_event,

child_event = perf_event_alloc(&parent_event->attr,
parent_event->cpu,
child,
group_leader, parent_event,
NULL);
if (IS_ERR(child_event))
Expand Down

0 comments on commit fd80b10

Please sign in to comment.