forked from Minki/linux
perf_counter: Always schedule all software counters in
Software counters aren't subject to the limitations imposed by the fixed number of hardware counter registers, so there is no reason not to enable them all in __perf_counter_sched_in. Previously we used to break out of the loop when we got to a group that wouldn't fit on the PMU; with this we continue through the list but only schedule in software counters (or groups containing only software counters) from there on. Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
c0d362a832
commit
dd0e6ba22e
@ -455,12 +455,37 @@ group_error:
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 1 for a software counter, 0 for a hardware counter
|
||||
*/
|
||||
static inline int is_software_counter(struct perf_counter *counter)
|
||||
{
|
||||
return !counter->hw_event.raw && counter->hw_event.type < 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 1 for a group consisting entirely of software counters,
|
||||
* 0 if the group contains any hardware counters.
|
||||
*/
|
||||
static int is_software_only_group(struct perf_counter *leader)
|
||||
{
|
||||
struct perf_counter *counter;
|
||||
|
||||
if (!is_software_counter(leader))
|
||||
return 0;
|
||||
list_for_each_entry(counter, &leader->sibling_list, list_entry)
|
||||
if (!is_software_counter(counter))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
__perf_counter_sched_in(struct perf_counter_context *ctx,
|
||||
struct perf_cpu_context *cpuctx, int cpu)
|
||||
{
|
||||
struct perf_counter *counter;
|
||||
u64 flags;
|
||||
int can_add_hw = 1;
|
||||
|
||||
if (likely(!ctx->nr_counters))
|
||||
return;
|
||||
@ -477,10 +502,12 @@ __perf_counter_sched_in(struct perf_counter_context *ctx,
|
||||
|
||||
/*
|
||||
* If we scheduled in a group atomically and exclusively,
|
||||
* or if this group can't go on, break out:
|
||||
* or if this group can't go on, don't add any more
|
||||
* hardware counters.
|
||||
*/
|
||||
if (group_sched_in(counter, cpuctx, ctx, cpu))
|
||||
break;
|
||||
if (can_add_hw || is_software_only_group(counter))
|
||||
if (group_sched_in(counter, cpuctx, ctx, cpu))
|
||||
can_add_hw = 0;
|
||||
}
|
||||
hw_perf_restore(flags);
|
||||
spin_unlock(&ctx->lock);
|
||||
|
Loading…
Reference in New Issue
Block a user