Commit 3b78990f authored by Stephane Eranian's avatar Stephane Eranian Committed by Xie Haocheng
Browse files

ACPI: Add perf low power callback

mainline inclusion
from mainline-v5.19
commit 2a606a18
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5S3WV


CVE: NA

-------------------------------------------------

Add an optional callback needed by some PMU features, e.g., AMD
BRS, to give a chance to the perf_events code to change its state before
a CPU goes to low power and after it comes back.

The callback is void when the PERF_NEEDS_LOPWR_CB flag is not set.
This flag must be set in arch specific perf_event.h header whenever needed.
When not set, there is no impact on the ACPI code.

Signed-off-by: default avatarStephane Eranian <eranian@google.com>
[peterz: build fix]
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220322221517.2510440-9-eranian@google.com


Signed-off-by: default avatarXie Haocheng <haocheng.xie@amd.com>
parent c7f8cd15
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/tick.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/perf_event.h>
#include <asm/mwait.h>
#include <xen/xen.h>

@@ -163,6 +164,9 @@ static int power_saving_thread(void *data)
				tsc_marked_unstable = 1;
			}
			local_irq_disable();

			perf_lopwr_cb(true);

			tick_broadcast_enable();
			tick_broadcast_enter();
			stop_critical_timings();
@@ -171,6 +175,9 @@ static int power_saving_thread(void *data)

			start_critical_timings();
			tick_broadcast_exit();

			perf_lopwr_cb(false);

			local_irq_enable();

			if (time_before(expire_time, jiffies)) {
+5 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/tick.h>
#include <linux/cpuidle.h>
#include <linux/cpu.h>
#include <linux/perf_event.h>
#include <acpi/processor.h>

/*
@@ -568,6 +569,8 @@ static void wait_for_freeze(void)
 */
static void __cpuidle acpi_idle_do_entry(struct acpi_processor_cx *cx)
{
	perf_lopwr_cb(true);

	if (cx->entry_method == ACPI_CSTATE_FFH) {
		/* Call into architectural FFH based C-state */
		acpi_processor_ffh_cstate_enter(cx);
@@ -578,6 +581,8 @@ static void __cpuidle acpi_idle_do_entry(struct acpi_processor_cx *cx)
		inb(cx->address);
		wait_for_freeze();
	}

	perf_lopwr_cb(false);
}

/**
+7 −0
Original line number Diff line number Diff line
@@ -1624,4 +1624,11 @@ extern void __weak arch_perf_update_userpage(struct perf_event *event,
					     struct perf_event_mmap_page *userpg,
					     u64 now);


#ifndef PERF_NEEDS_LOPWR_CB
static inline void perf_lopwr_cb(bool mode)
{
}
#endif

#endif /* _LINUX_PERF_EVENT_H */