perf/x86: Add flags to event constraints
This patch adds a flags field to each event constraint. It can be used to store event specific features which can then later be used by scheduling code or low-level x86 code. The flags are propagated into event->hw.flags during the get_event_constraint() call. They are cleared during the put_event_constraint() call. This mechanism is going to be used by the PEBS-LL patches. It avoids defining yet another table to hold event specific information. Signed-off-by: Stephane Eranian <eranian@google.com> Cc: peterz@infradead.org Cc: ak@linux.intel.com Cc: jolsa@redhat.com Cc: namhyung.kim@lge.com Link: http://lkml.kernel.org/r/1359040242-8269-4-git-send-email-eranian@google.com Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
3a54aaa0a3
commit
9fac2cf316
6 changed files with 16 additions and 7 deletions
|
|
@ -1489,7 +1489,7 @@ static int __init init_hw_perf_events(void)
|
||||||
|
|
||||||
unconstrained = (struct event_constraint)
|
unconstrained = (struct event_constraint)
|
||||||
__EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
|
__EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
|
||||||
0, x86_pmu.num_counters, 0);
|
0, x86_pmu.num_counters, 0, 0);
|
||||||
|
|
||||||
x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
|
x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
|
||||||
x86_pmu_format_group.attrs = x86_pmu.format_attrs;
|
x86_pmu_format_group.attrs = x86_pmu.format_attrs;
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ struct event_constraint {
|
||||||
u64 cmask;
|
u64 cmask;
|
||||||
int weight;
|
int weight;
|
||||||
int overlap;
|
int overlap;
|
||||||
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct amd_nb {
|
struct amd_nb {
|
||||||
|
|
@ -170,16 +171,17 @@ struct cpu_hw_events {
|
||||||
void *kfree_on_online;
|
void *kfree_on_online;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define __EVENT_CONSTRAINT(c, n, m, w, o) {\
|
#define __EVENT_CONSTRAINT(c, n, m, w, o, f) {\
|
||||||
{ .idxmsk64 = (n) }, \
|
{ .idxmsk64 = (n) }, \
|
||||||
.code = (c), \
|
.code = (c), \
|
||||||
.cmask = (m), \
|
.cmask = (m), \
|
||||||
.weight = (w), \
|
.weight = (w), \
|
||||||
.overlap = (o), \
|
.overlap = (o), \
|
||||||
|
.flags = f, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EVENT_CONSTRAINT(c, n, m) \
|
#define EVENT_CONSTRAINT(c, n, m) \
|
||||||
__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0)
|
__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0, 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The overlap flag marks event constraints with overlapping counter
|
* The overlap flag marks event constraints with overlapping counter
|
||||||
|
|
@ -203,7 +205,7 @@ struct cpu_hw_events {
|
||||||
* and its counter masks must be kept at a minimum.
|
* and its counter masks must be kept at a minimum.
|
||||||
*/
|
*/
|
||||||
#define EVENT_CONSTRAINT_OVERLAP(c, n, m) \
|
#define EVENT_CONSTRAINT_OVERLAP(c, n, m) \
|
||||||
__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 1)
|
__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 1, 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constraint on the Event code.
|
* Constraint on the Event code.
|
||||||
|
|
|
||||||
|
|
@ -1392,8 +1392,11 @@ x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
|
||||||
|
|
||||||
if (x86_pmu.event_constraints) {
|
if (x86_pmu.event_constraints) {
|
||||||
for_each_event_constraint(c, x86_pmu.event_constraints) {
|
for_each_event_constraint(c, x86_pmu.event_constraints) {
|
||||||
if ((event->hw.config & c->cmask) == c->code)
|
if ((event->hw.config & c->cmask) == c->code) {
|
||||||
|
/* hw.flags zeroed at initialization */
|
||||||
|
event->hw.flags |= c->flags;
|
||||||
return c;
|
return c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1438,6 +1441,7 @@ intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc,
|
||||||
static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
|
static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
|
||||||
struct perf_event *event)
|
struct perf_event *event)
|
||||||
{
|
{
|
||||||
|
event->hw.flags = 0;
|
||||||
intel_put_shared_regs_event_constraints(cpuc, event);
|
intel_put_shared_regs_event_constraints(cpuc, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -430,8 +430,10 @@ struct event_constraint *intel_pebs_constraints(struct perf_event *event)
|
||||||
|
|
||||||
if (x86_pmu.pebs_constraints) {
|
if (x86_pmu.pebs_constraints) {
|
||||||
for_each_event_constraint(c, x86_pmu.pebs_constraints) {
|
for_each_event_constraint(c, x86_pmu.pebs_constraints) {
|
||||||
if ((event->hw.config & c->cmask) == c->code)
|
if ((event->hw.config & c->cmask) == c->code) {
|
||||||
|
event->hw.flags |= c->flags;
|
||||||
return c;
|
return c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2438,7 +2438,7 @@ static int __init uncore_type_init(struct intel_uncore_type *type)
|
||||||
|
|
||||||
type->unconstrainted = (struct event_constraint)
|
type->unconstrainted = (struct event_constraint)
|
||||||
__EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,
|
__EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,
|
||||||
0, type->num_counters, 0);
|
0, type->num_counters, 0, 0);
|
||||||
|
|
||||||
for (i = 0; i < type->num_boxes; i++) {
|
for (i = 0; i < type->num_boxes; i++) {
|
||||||
pmus[i].func_id = -1;
|
pmus[i].func_id = -1;
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@ struct hw_perf_event {
|
||||||
int event_base_rdpmc;
|
int event_base_rdpmc;
|
||||||
int idx;
|
int idx;
|
||||||
int last_cpu;
|
int last_cpu;
|
||||||
|
int flags;
|
||||||
|
|
||||||
struct hw_perf_event_extra extra_reg;
|
struct hw_perf_event_extra extra_reg;
|
||||||
struct hw_perf_event_extra branch_reg;
|
struct hw_perf_event_extra branch_reg;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue