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

cpuidle: Fix ct_idle_*() usage



The whole disable-RCU, enable-IRQS dance is very intricate since
changing IRQ state is traced, which depends on RCU.

Add two helpers for the cpuidle case that mirror the entry code:

  ct_cpuidle_enter()
  ct_cpuidle_exit()

And fix all the cases where the enter/exit dance was buggy.

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>
Acked-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: default avatarFrederic Weisbecker <frederic@kernel.org>
Link: https://lore.kernel.org/r/20230112195540.130014793@infradead.org
parent 0c5ffc3d
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -25,9 +25,9 @@ static int imx6q_enter_wait(struct cpuidle_device *dev,
		imx6_set_lpm(WAIT_UNCLOCKED);
		imx6_set_lpm(WAIT_UNCLOCKED);
	raw_spin_unlock(&cpuidle_lock);
	raw_spin_unlock(&cpuidle_lock);


	ct_idle_enter();
	ct_cpuidle_enter();
	cpu_do_idle();
	cpu_do_idle();
	ct_idle_exit();
	ct_cpuidle_exit();


	raw_spin_lock(&cpuidle_lock);
	raw_spin_lock(&cpuidle_lock);
	if (num_idle_cpus-- == num_online_cpus())
	if (num_idle_cpus-- == num_online_cpus())
+2 −2
Original line number Original line Diff line number Diff line
@@ -47,9 +47,9 @@ static int imx6sx_enter_wait(struct cpuidle_device *dev,
		cpu_pm_enter();
		cpu_pm_enter();
		cpu_cluster_pm_enter();
		cpu_cluster_pm_enter();


		ct_idle_enter();
		ct_cpuidle_enter();
		cpu_suspend(0, imx6sx_idle_finish);
		cpu_suspend(0, imx6sx_idle_finish);
		ct_idle_exit();
		ct_cpuidle_exit();


		cpu_cluster_pm_exit();
		cpu_cluster_pm_exit();
		cpu_pm_exit();
		cpu_pm_exit();
+2 −2
Original line number Original line Diff line number Diff line
@@ -133,9 +133,9 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
	}
	}


	/* Execute ARM wfi */
	/* Execute ARM wfi */
	ct_idle_enter();
	ct_cpuidle_enter();
	omap_sram_idle();
	omap_sram_idle();
	ct_idle_exit();
	ct_cpuidle_exit();


	/*
	/*
	 * Call idle CPU PM enter notifier chain to restore
	 * Call idle CPU PM enter notifier chain to restore
+4 −4
Original line number Original line Diff line number Diff line
@@ -105,9 +105,9 @@ static int omap_enter_idle_smp(struct cpuidle_device *dev,
	}
	}
	raw_spin_unlock_irqrestore(&mpu_lock, flag);
	raw_spin_unlock_irqrestore(&mpu_lock, flag);


	ct_idle_enter();
	ct_cpuidle_enter();
	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
	ct_idle_exit();
	ct_cpuidle_exit();


	raw_spin_lock_irqsave(&mpu_lock, flag);
	raw_spin_lock_irqsave(&mpu_lock, flag);
	if (cx->mpu_state_vote == num_online_cpus())
	if (cx->mpu_state_vote == num_online_cpus())
@@ -186,10 +186,10 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
		}
		}
	}
	}


	ct_idle_enter();
	ct_cpuidle_enter();
	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
	cpu_done[dev->cpu] = true;
	cpu_done[dev->cpu] = true;
	ct_idle_exit();
	ct_cpuidle_exit();


	/* Wakeup CPU1 only if it is not offlined */
	/* Wakeup CPU1 only if it is not offlined */
	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
+6 −2
Original line number Original line Diff line number Diff line
@@ -642,6 +642,8 @@ static int __cpuidle acpi_idle_enter_bm(struct cpuidle_driver *drv,
	 */
	 */
	bool dis_bm = pr->flags.bm_control;
	bool dis_bm = pr->flags.bm_control;


	instrumentation_begin();

	/* If we can skip BM, demote to a safe state. */
	/* If we can skip BM, demote to a safe state. */
	if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
	if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
		dis_bm = false;
		dis_bm = false;
@@ -663,11 +665,11 @@ static int __cpuidle acpi_idle_enter_bm(struct cpuidle_driver *drv,
		raw_spin_unlock(&c3_lock);
		raw_spin_unlock(&c3_lock);
	}
	}


	ct_idle_enter();
	ct_cpuidle_enter();


	acpi_idle_do_entry(cx);
	acpi_idle_do_entry(cx);


	ct_idle_exit();
	ct_cpuidle_exit();


	/* Re-enable bus master arbitration */
	/* Re-enable bus master arbitration */
	if (dis_bm) {
	if (dis_bm) {
@@ -677,6 +679,8 @@ static int __cpuidle acpi_idle_enter_bm(struct cpuidle_driver *drv,
		raw_spin_unlock(&c3_lock);
		raw_spin_unlock(&c3_lock);
	}
	}


	instrumentation_end();

	return index;
	return index;
}
}


Loading