Commit 5fca0d9f authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

cpuidle, tegra: Push RCU-idle into driver



Doing RCU-idle outside the driver, only to then temporarily enable it
again, at least twice, before going idle is suboptimal.

Notably once implicitly through the cpu_pm_*() calls and once
explicitly doing RCU_NONIDLE().

Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Tested-by: default avatarTony Lindgren <tony@atomide.com>
Tested-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Reviewed-by: default avatarFrederic Weisbecker <frederic@kernel.org>
Acked-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://lore.kernel.org/r/20230112195539.699546331@infradead.org
parent 8e9ab9e8
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -180,9 +180,11 @@ static int tegra_cpuidle_state_enter(struct cpuidle_device *dev,
	}

	local_fiq_disable();
	RCU_NONIDLE(tegra_pm_set_cpu_in_lp2());
	tegra_pm_set_cpu_in_lp2();
	cpu_pm_enter();

	ct_idle_enter();

	switch (index) {
	case TEGRA_C7:
		err = tegra_cpuidle_c7_enter();
@@ -197,8 +199,10 @@ static int tegra_cpuidle_state_enter(struct cpuidle_device *dev,
		break;
	}

	ct_idle_exit();

	cpu_pm_exit();
	RCU_NONIDLE(tegra_pm_clear_cpu_in_lp2());
	tegra_pm_clear_cpu_in_lp2();
	local_fiq_enable();

	return err ?: index;
@@ -226,6 +230,7 @@ static int tegra_cpuidle_enter(struct cpuidle_device *dev,
			       struct cpuidle_driver *drv,
			       int index)
{
	bool do_rcu = drv->states[index].flags & CPUIDLE_FLAG_RCU_IDLE;
	unsigned int cpu = cpu_logical_map(dev->cpu);
	int ret;

@@ -233,9 +238,13 @@ static int tegra_cpuidle_enter(struct cpuidle_device *dev,
	if (dev->states_usage[index].disable)
		return -1;

	if (index == TEGRA_C1)
	if (index == TEGRA_C1) {
		if (do_rcu)
			ct_idle_enter();
		ret = arm_cpuidle_simple_enter(dev, drv, index);
	else
		if (do_rcu)
			ct_idle_exit();
	} else
		ret = tegra_cpuidle_state_enter(dev, index, cpu);

	if (ret < 0) {
@@ -285,7 +294,8 @@ static struct cpuidle_driver tegra_idle_driver = {
			.exit_latency		= 2000,
			.target_residency	= 2200,
			.power_usage		= 100,
			.flags			= CPUIDLE_FLAG_TIMER_STOP,
			.flags			= CPUIDLE_FLAG_TIMER_STOP |
						  CPUIDLE_FLAG_RCU_IDLE,
			.name			= "C7",
			.desc			= "CPU core powered off",
		},
@@ -295,6 +305,7 @@ static struct cpuidle_driver tegra_idle_driver = {
			.target_residency	= 10000,
			.power_usage		= 0,
			.flags			= CPUIDLE_FLAG_TIMER_STOP |
						  CPUIDLE_FLAG_RCU_IDLE   |
						  CPUIDLE_FLAG_COUPLED,
			.name			= "CC6",
			.desc			= "CPU cluster powered off",