When arch level event init is called, the event is not yet connected to the PMU, thereby causing validate_group() to always do dummy work. On MIPS, this is due to the following lines in validate_event() called by validate_group(): if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF) return 1; This patch fixes it. Signed-off-by: Deng-Cheng Zhu <dczhu@xxxxxxxx> Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx> Cc: Paul Mackerras <paulus@xxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxx> Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxxxxxxxxxx> Cc: David Daney <david.daney@xxxxxxxxxx> --- arch/mips/kernel/perf_event_mipsxx.c | 17 +++++++++++++---- 1 files changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 1f654ca..c804fdd 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -548,6 +548,7 @@ static int __hw_perf_event_init(struct perf_event *event) struct perf_event_attr *attr = &event->attr; struct hw_perf_event *hwc = &event->hw; const struct mips_perf_event *pev; + struct pmu *tmp; int err; /* Returning MIPS event descriptor for generic perf event. */ @@ -611,11 +612,19 @@ static int __hw_perf_event_init(struct perf_event *event) } err = 0; - if (event->group_leader != event) { + + /* + * we temporarily connect event to its pmu such that + * validate_event() in validate_group() can classify + * it as a MIPS event by passing (event->pmu == &pmu). + */ + tmp = event->pmu; + event->pmu = &pmu; + + if (event->group_leader != event) err = validate_group(event); - if (err) - return -EINVAL; - } + + event->pmu = tmp; event->destroy = hw_perf_event_destroy; -- 1.7.1