summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRemy Noel <mocramis@gmail.com>2018-04-06 19:41:33 +0200
committerRemy Noel <mocramis@gmail.com>2018-04-21 00:04:20 +0200
commit7f545f440e58b081b1ff630e78903ee4ee901a5a (patch)
tree332c4203078b678b51d94e0e5d8a66ef8ba4093a
parentf6f54a518bb2f35b5f222de7288ebf2cae67fca2 (diff)
kern/perfmon.c: Add pmc id to index map.
Will be used to handle calls from the pmu implementations.
-rw-r--r--kern/perfmon.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/kern/perfmon.c b/kern/perfmon.c
index d42fd09..5627726 100644
--- a/kern/perfmon.c
+++ b/kern/perfmon.c
@@ -183,6 +183,8 @@ struct perfmon_cpu_pmu {
static struct perfmon_pmu_ops pmu_driver __read_mostly;
static struct perfmon_pmu perfmon_pmu;
+static unsigned int perfmon_pmc_id_to_index[PERFMON_MAX_PMCS];
+
static struct perfmon_cpu_pmu perfmon_cpu_pmu __percpu;
/*
@@ -264,6 +266,16 @@ perfmon_pmc_lookup(unsigned int raw_event_id)
return NULL;
}
+static inline unsigned int
+perfmon_pmc_index(const struct perfmon_pmc *pmc)
+{
+ unsigned int index;
+
+ index = pmc - perfmon_pmu.pmcs;
+ assert(index < ARRAY_SIZE(perfmon_pmu.pmcs));
+ return index;
+}
+
/*
* Obtain a reference on a PMC for the given event.
*
@@ -274,6 +286,7 @@ perfmon_pmc_get(struct perfmon_pmc **pmcp, const struct perfmon_event *event)
{
struct perfmon_pmc *pmc;
unsigned int raw_event_id;
+ unsigned int pmc_index;
int error;
error = perfmon_translate(&raw_event_id, event->type, event->id);
@@ -292,6 +305,9 @@ perfmon_pmc_get(struct perfmon_pmc **pmcp, const struct perfmon_event *event)
if (error) {
goto out;
}
+ pmc_index = perfmon_pmc_index(pmc);
+ assert(perfmon_pmc_id_to_index[pmc->id] == UINT32_MAX);
+ perfmon_pmc_id_to_index[pmc->id] = pmc_index;
}
pmc->nr_refs++;
@@ -320,21 +336,13 @@ perfmon_pmc_put(struct perfmon_pmc *pmc)
if (pmc->nr_refs == 0) {
pmu_driver.free(pmc->id);
+ assert(perfmon_pmc_id_to_index[pmc->id] != UINT32_MAX);
+ perfmon_pmc_id_to_index[pmc->id] = UINT32_MAX;
}
spinlock_unlock(&perfmon_pmu.lock);
}
-static inline unsigned int
-perfmon_pmc_index(const struct perfmon_pmc *pmc)
-{
- unsigned int index;
-
- index = pmc - perfmon_pmu.pmcs;
- assert(index < ARRAY_SIZE(perfmon_pmu.pmcs));
- return index;
-}
-
static inline struct perfmon_pmc *
perfmon_pmc_from_index(unsigned int index)
{
@@ -451,6 +459,9 @@ perfmon_setup(void)
for (i = 0; i < ARRAY_SIZE(perfmon_pmu.pmcs); i++) {
perfmon_pmu.pmcs[i].nr_refs = 0;
}
+ for (i = 0; i < ARRAY_SIZE(perfmon_pmc_id_to_index); i++) {
+ perfmon_pmc_id_to_index[i] = UINT32_MAX;
+ }
for (i = 0; i < cpu_count(); i++) {
perfmon_cpu_pmu_init(percpu_ptr(perfmon_cpu_pmu, i));