Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03b7898d authored by Mark Rutland's avatar Mark Rutland Committed by Will Deacon
Browse files

ARM: perf: move active_events into struct arm_pmu



This patch moves the active_events counter into struct arm_pmu, in
preparation for supporting multiple PMUs. This also moves
pmu_reserve_mutex, as it is used to guard accesses to active_events.

Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Reviewed-by: default avatarWill Deacon <will.deacon@arm.com>
Reviewed-by: default avatarJamie Iles <jamie@jamieiles.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent c47f8684
Loading
Loading
Loading
Loading
+20 −11
Original line number Diff line number Diff line
@@ -82,6 +82,8 @@ struct arm_pmu {
	const unsigned	(*event_map)[PERF_COUNT_HW_MAX];
	u32		raw_event_mask;
	int		num_events;
	atomic_t	active_events;
	struct mutex	reserve_mutex;
	u64		max_period;
};

@@ -454,15 +456,15 @@ armpmu_reserve_hardware(void)
	return 0;
}

static atomic_t active_events = ATOMIC_INIT(0);
static DEFINE_MUTEX(pmu_reserve_mutex);

static void
hw_perf_event_destroy(struct perf_event *event)
{
	if (atomic_dec_and_mutex_lock(&active_events, &pmu_reserve_mutex)) {
	atomic_t *active_events	 = &armpmu->active_events;
	struct mutex *pmu_reserve_mutex = &armpmu->reserve_mutex;

	if (atomic_dec_and_mutex_lock(active_events, pmu_reserve_mutex)) {
		armpmu_release_hardware();
		mutex_unlock(&pmu_reserve_mutex);
		mutex_unlock(pmu_reserve_mutex);
	}
}

@@ -543,6 +545,7 @@ __hw_perf_event_init(struct perf_event *event)
static int armpmu_event_init(struct perf_event *event)
{
	int err = 0;
	atomic_t *active_events = &armpmu->active_events;

	switch (event->attr.type) {
	case PERF_TYPE_RAW:
@@ -556,15 +559,14 @@ static int armpmu_event_init(struct perf_event *event)

	event->destroy = hw_perf_event_destroy;

	if (!atomic_inc_not_zero(&active_events)) {
		mutex_lock(&pmu_reserve_mutex);
		if (atomic_read(&active_events) == 0) {
	if (!atomic_inc_not_zero(active_events)) {
		mutex_lock(&armpmu->reserve_mutex);
		if (atomic_read(active_events) == 0)
			err = armpmu_reserve_hardware();
		}

		if (!err)
			atomic_inc(&active_events);
		mutex_unlock(&pmu_reserve_mutex);
			atomic_inc(active_events);
		mutex_unlock(&armpmu->reserve_mutex);
	}

	if (err)
@@ -613,6 +615,12 @@ static struct pmu pmu = {
	.read		= armpmu_read,
};

static void __init armpmu_init(struct arm_pmu *armpmu)
{
	atomic_set(&armpmu->active_events, 0);
	mutex_init(&armpmu->reserve_mutex);
}

/* Include the PMU-specific implementations. */
#include "perf_event_xscale.c"
#include "perf_event_v6.c"
@@ -718,6 +726,7 @@ init_hw_perf_events(void)
	if (armpmu) {
		pr_info("enabled with %s PMU driver, %d counters available\n",
			armpmu->name, armpmu->num_events);
		armpmu_init(armpmu);
		perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
	} else {
		pr_info("no hardware support available\n");