Commit 976aa630 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more power management updates from Rafael Wysocki:
 "These revert an x86 commit that introduced a nasty power regression on
  some systems, fix PSCI cpuidle driver and ACPI cpufreq driver
  regressions, add Rust abstractions for cpufreq, OPP, clk, and
  cpumasks, add a Rust-based cpufreq-dt driver, and do a minor SCMI
  cpufreq driver cleanup:

   - Revert an x86 commit that went into 6.15 and caused idle power,
     including power in suspend-to-idle, to rise rather dramatically on
     systems booting with "nosmt" in the kernel command line (Rafael
     Wysocki)

   - Prevent freeing an uninitialized pointer in error path of
     dt_idle_state_present() in the PSCI cpuidle driver (Dan Carpenter)

   - Use KHz as the nominal_freq units in get_max_boost_ratio() in the
     ACPI cpufreq driver (iGautham Shenoy)

   - Add Rust abstractions for CPUFreq framework (Viresh Kumar)

   - Add Rust abstractions for OPP framework (Viresh Kumar)

   - Add basic Rust abstractions for Clk and Cpumask frameworks (Viresh
     Kumar)

   - Clean up the SCMI cpufreq driver somewhat (Mike Tipton)"

* tag 'pm-6.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (21 commits)
  Revert "x86/smp: Eliminate mwait_play_dead_cpuid_hint()"
  acpi-cpufreq: Fix nominal_freq units to KHz in get_max_boost_ratio()
  rust: opp: Move `cfg(CONFIG_OF)` attribute to the top of doc test
  cpuidle: psci: Fix uninitialized variable in dt_idle_state_present()
  rust: opp: Make the doctest example depend on CONFIG_OF
  cpufreq: scmi: Skip SCMI devices that aren't used by the CPUs
  cpufreq: Add Rust-based cpufreq-dt driver
  rust: opp: Extend OPP abstractions with cpufreq support
  rust: cpufreq: Extend abstractions for driver registration
  rust: cpufreq: Extend abstractions for policy and driver ops
  rust: cpufreq: Add initial abstractions for cpufreq framework
  rust: opp: Add abstractions for the configuration options
  rust: opp: Add abstractions for the OPP table
  rust: opp: Add initial abstractions for OPP framework
  rust: cpu: Add from_cpu()
  rust: macros: enable use of hyphens in module names
  rust: clk: Add initial abstractions
  rust: clk: Add helpers for Rust code
  MAINTAINERS: Add entry for Rust cpumask API
  rust: cpumask: Add initial abstractions
  ...
parents 8477ab14 3d031d0d
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -5952,6 +5952,8 @@ F: include/dt-bindings/clock/
F:	include/linux/clk-pr*
F:	include/linux/clk/
F:	include/linux/of_clk.h
F:	rust/helpers/clk.c
F:	rust/kernel/clk.rs
X:	drivers/clk/clkdev.c
COMMON INTERNET FILE SYSTEM CLIENT (CIFS and SMB3)
@@ -6211,6 +6213,7 @@ F: drivers/cpufreq/
F:	include/linux/cpufreq.h
F:	include/linux/sched/cpufreq.h
F:	kernel/sched/cpufreq*.c
F:	rust/kernel/cpufreq.rs
F:	tools/testing/selftests/cpufreq/
CPU HOTPLUG
@@ -6224,6 +6227,7 @@ F: include/linux/cpuhotplug.h
F:	include/linux/smpboot.h
F:	kernel/cpu.c
F:	kernel/smpboot.*
F:	rust/kernel/cpu.rs
CPU IDLE TIME MANAGEMENT FRAMEWORK
M:	"Rafael J. Wysocki" <rafael@kernel.org>
@@ -6308,6 +6312,12 @@ L: linux-riscv@lists.infradead.org
S:	Maintained
F:	drivers/cpuidle/cpuidle-riscv-sbi.c
CPUMASK API [RUST]
M:	Viresh Kumar <viresh.kumar@linaro.org>
R:	Yury Norov <yury.norov@gmail.com>
S:	Maintained
F:	rust/kernel/cpumask.rs
CRAMFS FILESYSTEM
M:	Nicolas Pitre <nico@fluxnic.net>
S:	Maintained
@@ -18514,6 +18524,7 @@ F: Documentation/devicetree/bindings/opp/
F:	Documentation/power/opp.rst
F:	drivers/opp/
F:	include/linux/pm_opp.h
F:	rust/kernel/opp.rs
OPL4 DRIVER
M:	Clemens Ladisch <clemens@ladisch.de>
+47 −7
Original line number Diff line number Diff line
@@ -1244,10 +1244,6 @@ void play_dead_common(void)
	local_irq_disable();
}

/*
 * We need to flush the caches before going to sleep, lest we have
 * dirty data in our caches when we come back up.
 */
void __noreturn mwait_play_dead(unsigned int eax_hint)
{
	struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead);
@@ -1293,6 +1289,50 @@ void __noreturn mwait_play_dead(unsigned int eax_hint)
	}
}

/*
 * We need to flush the caches before going to sleep, lest we have
 * dirty data in our caches when we come back up.
 */
static inline void mwait_play_dead_cpuid_hint(void)
{
	unsigned int eax, ebx, ecx, edx;
	unsigned int highest_cstate = 0;
	unsigned int highest_subcstate = 0;
	int i;

	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
	    boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
		return;
	if (!this_cpu_has(X86_FEATURE_MWAIT))
		return;
	if (!this_cpu_has(X86_FEATURE_CLFLUSH))
		return;

	eax = CPUID_LEAF_MWAIT;
	ecx = 0;
	native_cpuid(&eax, &ebx, &ecx, &edx);

	/*
	 * eax will be 0 if EDX enumeration is not valid.
	 * Initialized below to cstate, sub_cstate value when EDX is valid.
	 */
	if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) {
		eax = 0;
	} else {
		edx >>= MWAIT_SUBSTATE_SIZE;
		for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
			if (edx & MWAIT_SUBSTATE_MASK) {
				highest_cstate = i;
				highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
			}
		}
		eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
			(highest_subcstate - 1);
	}

	mwait_play_dead(eax);
}

/*
 * Kick all "offline" CPUs out of mwait on kexec(). See comment in
 * mwait_play_dead().
@@ -1343,8 +1383,8 @@ void native_play_dead(void)
	play_dead_common();
	tboot_shutdown(TB_SHUTDOWN_WFS);

	/* Below returns only on error. */
	cpuidle_play_dead();
	mwait_play_dead_cpuid_hint();
	if (cpuidle_play_dead())
		hlt_play_dead();
}

+12 −0
Original line number Diff line number Diff line
@@ -217,6 +217,18 @@ config CPUFREQ_DT

	  If in doubt, say N.

config CPUFREQ_DT_RUST
	tristate "Rust based Generic DT based cpufreq driver"
	depends on HAVE_CLK && OF && RUST
	select CPUFREQ_DT_PLATDEV
	select PM_OPP
	help
	  This adds a Rust based generic DT based cpufreq driver for frequency
	  management.  It supports both uniprocessor (UP) and symmetric
	  multiprocessor (SMP) systems.

	  If in doubt, say N.

config CPUFREQ_VIRT
	tristate "Virtual cpufreq driver"
	depends on GENERIC_ARCH_TOPOLOGY
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o
obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET)	+= cpufreq_governor_attr_set.o

obj-$(CONFIG_CPUFREQ_DT)		+= cpufreq-dt.o
obj-$(CONFIG_CPUFREQ_DT_RUST)		+= rcpufreq_dt.o
obj-$(CONFIG_CPUFREQ_DT_PLATDEV)	+= cpufreq-dt-platdev.o
obj-$(CONFIG_CPUFREQ_VIRT)		+= virtual-cpufreq.o

+1 −1
Original line number Diff line number Diff line
@@ -660,7 +660,7 @@ static u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq)
	nominal_perf = perf_caps.nominal_perf;

	if (nominal_freq)
		*nominal_freq = perf_caps.nominal_freq;
		*nominal_freq = perf_caps.nominal_freq * 1000;

	if (!highest_perf || !nominal_perf) {
		pr_debug("CPU%d: highest or nominal performance missing\n", cpu);
Loading