From 7572bdf9ec0994202b05d06944c20a6feb431960 Mon Sep 17 00:00:00 2001 From: Jayachandran C Date: Tue, 23 Aug 2011 13:35:08 +0530 Subject: [PATCH] --- yaml --- r: 284778 b: refs/heads/master c: e6be33cf6bd534a78dd623a3d2d7dbba4d0e832a h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/mips/kernel/perf_event_mipsxx.c | 72 ++++++++++++++++++---- trunk/arch/mips/netlogic/Platform | 2 +- 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/[refs] b/[refs] index f7d4ee1e0bef..8eb65d8eeb95 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ff5d7265cfb88e8f8943a55afde90255fc5deacb +refs/heads/master: e6be33cf6bd534a78dd623a3d2d7dbba4d0e832a diff --git a/trunk/arch/mips/kernel/perf_event_mipsxx.c b/trunk/arch/mips/kernel/perf_event_mipsxx.c index bda4bc9e6988..4f2971bcf8e5 100644 --- a/trunk/arch/mips/kernel/perf_event_mipsxx.c +++ b/trunk/arch/mips/kernel/perf_event_mipsxx.c @@ -621,6 +621,11 @@ static int mipspmu_event_init(struct perf_event *event) return -ENODEV; if (!atomic_inc_not_zero(&active_events)) { + if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) { + atomic_dec(&active_events); + return -ENOSPC; + } + mutex_lock(&pmu_reserve_mutex); if (atomic_read(&active_events) == 0) err = mipspmu_get_irq(); @@ -633,7 +638,11 @@ static int mipspmu_event_init(struct perf_event *event) if (err) return err; - return __hw_perf_event_init(event); + err = __hw_perf_event_init(event); + if (err) + hw_perf_event_destroy(event); + + return err; } static struct pmu pmu = { @@ -703,6 +712,18 @@ static const struct mips_perf_event *mipspmu_map_cache_event(u64 config) } +static int validate_event(struct cpu_hw_events *cpuc, + struct perf_event *event) +{ + struct hw_perf_event fake_hwc = event->hw; + + /* Allow mixed event group. So return 1 to pass validation. */ + if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF) + return 1; + + return mipsxx_pmu_alloc_counter(cpuc, &fake_hwc) >= 0; +} + static int validate_group(struct perf_event *event) { struct perf_event *sibling, *leader = event->group_leader; @@ -710,15 +731,15 @@ static int validate_group(struct perf_event *event) memset(&fake_cpuc, 0, sizeof(fake_cpuc)); - if (mipsxx_pmu_alloc_counter(&fake_cpuc, &leader->hw) < 0) + if (!validate_event(&fake_cpuc, leader)) return -ENOSPC; list_for_each_entry(sibling, &leader->sibling_list, group_entry) { - if (mipsxx_pmu_alloc_counter(&fake_cpuc, &sibling->hw) < 0) + if (!validate_event(&fake_cpuc, sibling)) return -ENOSPC; } - if (mipsxx_pmu_alloc_counter(&fake_cpuc, &event->hw) < 0) + if (!validate_event(&fake_cpuc, event)) return -ENOSPC; return 0; @@ -1258,14 +1279,13 @@ static int __hw_perf_event_init(struct perf_event *event) } err = 0; - if (event->group_leader != event) + if (event->group_leader != event) { err = validate_group(event); + if (err) + return -EINVAL; + } event->destroy = hw_perf_event_destroy; - - if (err) - event->destroy(event); - return err; } @@ -1360,10 +1380,20 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev) } /* 24K */ +#define IS_UNSUPPORTED_24K_EVENT(r, b) \ + ((b) == 12 || (r) == 151 || (r) == 152 || (b) == 26 || \ + (b) == 27 || (r) == 28 || (r) == 158 || (b) == 31 || \ + (b) == 32 || (b) == 34 || (b) == 36 || (r) == 168 || \ + (r) == 172 || (b) == 47 || ((b) >= 56 && (b) <= 63) || \ + ((b) >= 68 && (b) <= 127)) #define IS_BOTH_COUNTERS_24K_EVENT(b) \ ((b) == 0 || (b) == 1 || (b) == 11) /* 34K */ +#define IS_UNSUPPORTED_34K_EVENT(r, b) \ + ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 36 || \ + (b) == 38 || (r) == 175 || ((b) >= 56 && (b) <= 63) || \ + ((b) >= 68 && (b) <= 127)) #define IS_BOTH_COUNTERS_34K_EVENT(b) \ ((b) == 0 || (b) == 1 || (b) == 11) #ifdef CONFIG_MIPS_MT_SMP @@ -1376,10 +1406,20 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev) #endif /* 74K */ +#define IS_UNSUPPORTED_74K_EVENT(r, b) \ + ((r) == 5 || ((r) >= 135 && (r) <= 137) || \ + ((b) >= 10 && (b) <= 12) || (b) == 22 || (b) == 27 || \ + (b) == 33 || (b) == 34 || ((b) >= 47 && (b) <= 49) || \ + (r) == 178 || (b) == 55 || (b) == 57 || (b) == 60 || \ + (b) == 61 || (r) == 62 || (r) == 191 || \ + ((b) >= 64 && (b) <= 127)) #define IS_BOTH_COUNTERS_74K_EVENT(b) \ ((b) == 0 || (b) == 1) /* 1004K */ +#define IS_UNSUPPORTED_1004K_EVENT(r, b) \ + ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 38 || \ + (r) == 175 || (b) == 63 || ((b) >= 68 && (b) <= 127)) #define IS_BOTH_COUNTERS_1004K_EVENT(b) \ ((b) == 0 || (b) == 1 || (b) == 11) #ifdef CONFIG_MIPS_MT_SMP @@ -1405,10 +1445,11 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) unsigned int raw_id = config & 0xff; unsigned int base_id = raw_id & 0x7f; - raw_event.event_id = base_id; - switch (current_cpu_type()) { case CPU_24K: + if (IS_UNSUPPORTED_24K_EVENT(raw_id, base_id)) + return ERR_PTR(-EOPNOTSUPP); + raw_event.event_id = base_id; if (IS_BOTH_COUNTERS_24K_EVENT(base_id)) raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; else @@ -1423,6 +1464,9 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) #endif break; case CPU_34K: + if (IS_UNSUPPORTED_34K_EVENT(raw_id, base_id)) + return ERR_PTR(-EOPNOTSUPP); + raw_event.event_id = base_id; if (IS_BOTH_COUNTERS_34K_EVENT(base_id)) raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; else @@ -1438,6 +1482,9 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) #endif break; case CPU_74K: + if (IS_UNSUPPORTED_74K_EVENT(raw_id, base_id)) + return ERR_PTR(-EOPNOTSUPP); + raw_event.event_id = base_id; if (IS_BOTH_COUNTERS_74K_EVENT(base_id)) raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; else @@ -1448,6 +1495,9 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) #endif break; case CPU_1004K: + if (IS_UNSUPPORTED_1004K_EVENT(raw_id, base_id)) + return ERR_PTR(-EOPNOTSUPP); + raw_event.event_id = base_id; if (IS_BOTH_COUNTERS_1004K_EVENT(base_id)) raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; else diff --git a/trunk/arch/mips/netlogic/Platform b/trunk/arch/mips/netlogic/Platform index b648b487fd66..502d912b23ea 100644 --- a/trunk/arch/mips/netlogic/Platform +++ b/trunk/arch/mips/netlogic/Platform @@ -13,4 +13,4 @@ cflags-$(CONFIG_NLM_XLR) += $(call cc-option,-march=xlr,-march=mips64) # NETLOGIC XLR/XLS SoC, Simulator and boards # core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/ -load-$(CONFIG_NLM_XLR_BOARD) += 0xffffffff84000000 +load-$(CONFIG_NLM_XLR_BOARD) += 0xffffffff80100000