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

Commit d3b27cc5 authored by Ashwin Chaugule's avatar Ashwin Chaugule Committed by Stephen Boyd
Browse files

Perf: Re-enable counters after power collapse



Counters need to be individually re-enabled after the CPU
comes out of power collapse. Without this the counters
will simply be set to their MAX period and starting the PMU
will have no effect.

Change-Id: I3988a45277057eb80cf580b90ce697d0e6a00c43
Signed-off-by: default avatarAshwin Chaugule <ashwinc@codeaurora.org>
parent 38655ce3
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -76,6 +76,12 @@ struct arm_pmu {
	struct pmu	pmu;
	cpumask_t	active_irqs;
	char		*name;
	int		num_events;
	atomic_t	active_events;
	struct mutex	reserve_mutex;
	u64		max_period;
	struct platform_device	*plat_device;
	u32		from_idle;
	irqreturn_t	(*handle_irq)(int irq_num, void *dev);
	void		(*enable)(struct perf_event *event);
	void		(*disable)(struct perf_event *event);
@@ -91,11 +97,6 @@ struct arm_pmu {
	int		(*request_irq)(struct arm_pmu *, irq_handler_t handler);
	void		(*free_irq)(struct arm_pmu *);
	int		(*map_event)(struct perf_event *event);
	int		num_events;
	atomic_t	active_events;
	struct mutex	reserve_mutex;
	u64		max_period;
	struct platform_device	*plat_device;
	struct pmu_hw_events	*(*get_hw_events)(void);
	int	(*test_set_event_constraints)(struct perf_event *event);
	int	(*clear_event_constraints)(struct perf_event *event);
+15 −0
Original line number Diff line number Diff line
@@ -467,6 +467,21 @@ static void armpmu_enable(struct pmu *pmu)
	struct arm_pmu *armpmu = to_arm_pmu(pmu);
	struct pmu_hw_events *hw_events = armpmu->get_hw_events();
	int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
	int idx;

	if (armpmu->from_idle) {
		for (idx = 0; idx <= cpu_pmu->num_events; ++idx) {
			struct perf_event *event = hw_events->events[idx];

			if (!event)
				continue;

			armpmu->enable(&event->hw, idx, event->cpu);
		}

		/* Reset bit so we don't needlessly re-enable counters.*/
		armpmu->from_idle = 0;
	}

	if (enabled)
		armpmu->start(armpmu);
+6 −0
Original line number Diff line number Diff line
@@ -231,10 +231,16 @@ static int perf_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd,
	case CPU_PM_ENTER_FAILED:
	case CPU_PM_EXIT:
		if (cpu_has_active_perf() && cpu_pmu->reset) {
			/*
			 * Flip this bit so armpmu_enable knows it needs
			 * to re-enable active counters.
			 */
			cpu_pmu->from_idle = 1;
			cpu_pmu->reset(NULL);
			perf_pmu_enable(&cpu_pmu->pmu);
		}
		break;
		break;
	}

	return NOTIFY_OK;