Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 199097
b: refs/heads/master
c: a13c3af
h: refs/heads/master
i:
  199095: 7ff3109
v: v3
  • Loading branch information
Lin Ming authored and Ingo Molnar committed May 18, 2010
1 parent 59a48cb commit f641c5c
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 48 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: 6d1acfd5c6bfd5231c13a8f2858d7f2afbaa1b62
refs/heads/master: a13c3afd9b62b6dace80654964cc4ca7d2db8092
108 changes: 61 additions & 47 deletions trunk/arch/sparc/kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ struct cpu_hw_events {

/* Enabled/disable state. */
int enabled;

unsigned int group_flag;
};
DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };

Expand Down Expand Up @@ -980,53 +982,6 @@ static int collect_events(struct perf_event *group, int max_count,
return n;
}

static void event_sched_in(struct perf_event *event)
{
event->state = PERF_EVENT_STATE_ACTIVE;
event->oncpu = smp_processor_id();
event->tstamp_running += event->ctx->time - event->tstamp_stopped;
if (is_software_event(event))
event->pmu->enable(event);
}

int hw_perf_group_sched_in(struct perf_event *group_leader,
struct perf_cpu_context *cpuctx,
struct perf_event_context *ctx)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct perf_event *sub;
int n0, n;

if (!sparc_pmu)
return 0;

n0 = cpuc->n_events;
n = collect_events(group_leader, perf_max_events - n0,
&cpuc->event[n0], &cpuc->events[n0],
&cpuc->current_idx[n0]);
if (n < 0)
return -EAGAIN;
if (check_excludes(cpuc->event, n0, n))
return -EINVAL;
if (sparc_check_constraints(cpuc->event, cpuc->events, n + n0))
return -EAGAIN;
cpuc->n_events = n0 + n;
cpuc->n_added += n;

cpuctx->active_oncpu += n;
n = 1;
event_sched_in(group_leader);
list_for_each_entry(sub, &group_leader->sibling_list, group_entry) {
if (sub->state != PERF_EVENT_STATE_OFF) {
event_sched_in(sub);
n++;
}
}
ctx->nr_active += n;

return 1;
}

static int sparc_pmu_enable(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
Expand All @@ -1044,11 +999,20 @@ static int sparc_pmu_enable(struct perf_event *event)
cpuc->events[n0] = event->hw.event_base;
cpuc->current_idx[n0] = PIC_NO_INDEX;

/*
* If group events scheduling transaction was started,
* skip the schedulability test here, it will be peformed
* at commit time(->commit_txn) as a whole
*/
if (cpuc->group_flag & PERF_EVENT_TXN_STARTED)
goto nocheck;

if (check_excludes(cpuc->event, n0, 1))
goto out;
if (sparc_check_constraints(cpuc->event, cpuc->events, n0 + 1))
goto out;

nocheck:
cpuc->n_events++;
cpuc->n_added++;

Expand Down Expand Up @@ -1128,11 +1092,61 @@ static int __hw_perf_event_init(struct perf_event *event)
return 0;
}

/*
* Start group events scheduling transaction
* Set the flag to make pmu::enable() not perform the
* schedulability test, it will be performed at commit time
*/
static void sparc_pmu_start_txn(const struct pmu *pmu)
{
struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);

cpuhw->group_flag |= PERF_EVENT_TXN_STARTED;
}

/*
* Stop group events scheduling transaction
* Clear the flag and pmu::enable() will perform the
* schedulability test.
*/
static void sparc_pmu_cancel_txn(const struct pmu *pmu)
{
struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);

cpuhw->group_flag &= ~PERF_EVENT_TXN_STARTED;
}

/*
* Commit group events scheduling transaction
* Perform the group schedulability test as a whole
* Return 0 if success
*/
static int sparc_pmu_commit_txn(const struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
int n;

if (!sparc_pmu)
return -EINVAL;

cpuc = &__get_cpu_var(cpu_hw_events);
n = cpuc->n_events;
if (check_excludes(cpuc->event, 0, n))
return -EINVAL;
if (sparc_check_constraints(cpuc->event, cpuc->events, n))
return -EAGAIN;

return 0;
}

static const struct pmu pmu = {
.enable = sparc_pmu_enable,
.disable = sparc_pmu_disable,
.read = sparc_pmu_read,
.unthrottle = sparc_pmu_unthrottle,
.start_txn = sparc_pmu_start_txn,
.cancel_txn = sparc_pmu_cancel_txn,
.commit_txn = sparc_pmu_commit_txn,
};

const struct pmu *hw_perf_event_init(struct perf_event *event)
Expand Down

0 comments on commit f641c5c

Please sign in to comment.