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

Commit 1533a8d6 authored by Raghavendra Rao Ananta's avatar Raghavendra Rao Ananta Committed by Gerrit - the friendly Code Review server
Browse files

perf: Avoid cpu hotplug during event deletion



The event will not be successfully deleted if there was a CPU
hotplug going on. The change prevents that from happening.
Moreover, the change also disables the ARM PMU irq when the CPU
is coming down. This is due to the reason that the deletion
of perf event depends on freeing the irqs, which would happen
if the irq is disabled in the first place.

Change-Id: Ifc3860f723f76d1560e2c9d3fd507e5ead20462a
Signed-off-by: default avatarRaghavendra Rao Ananta <rananta@codeaurora.org>
parent 8cf945f5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ 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		percpu_irq;
	int		num_events;
	atomic_t	active_events;
	struct mutex	reserve_mutex;
+18 −5
Original line number Diff line number Diff line
@@ -200,15 +200,27 @@ static void cpu_pmu_init(struct arm_pmu *cpu_pmu)
static int cpu_pmu_notify(struct notifier_block *b, unsigned long action,
			  void *hcpu)
{
	if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
	unsigned long masked_action = action & ~CPU_TASKS_FROZEN;

	if (!cpu_pmu)
		return NOTIFY_DONE;

	if (cpu_pmu && cpu_pmu->reset)
		cpu_pmu->reset(cpu_pmu);
	else
	if ((masked_action != CPU_DYING) &&
		(masked_action != CPU_STARTING))
		return NOTIFY_DONE;

	return NOTIFY_OK;
	switch (masked_action) {
	case CPU_DYING:
		if (cpu_pmu->plat_device)
			disable_percpu_irq(cpu_pmu->percpu_irq);
		break;
	case CPU_STARTING:
		if (cpu_pmu->reset)
			cpu_pmu->reset(cpu_pmu);
		break;
	}

	return NOTIFY_DONE;
}

static struct notifier_block cpu_pmu_hotplug_notifier = {
@@ -312,6 +324,7 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)

	cpu_pmu = pmu;
	cpu_pmu->plat_device = pdev;
	cpu_pmu->percpu_irq = platform_get_irq(pdev, 0);

	if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) {
		init_fn = of_id->data;
+3 −0
Original line number Diff line number Diff line
@@ -3626,7 +3626,10 @@ static int perf_release(struct inode *inode, struct file *file)
	if ((event->state == PERF_EVENT_STATE_OFF) &&
	    event->attr.constraint_duplicate)
		event->state = PERF_EVENT_STATE_ACTIVE;

	get_online_cpus();
	put_event(file->private_data);
	put_online_cpus();
	return 0;
}