aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2023-12-26 02:19:28 +0000
committerAlexander Motin <mav@FreeBSD.org>2024-01-19 16:35:54 +0000
commitc71b398a155579d3bd31b3945013488bac5cb41e (patch)
tree88a213448a42c4392b5baba9099da6c6159d5244
parentc849f305614c51b9c71196012596266fb661c54c (diff)
acpi_cpu: Reduce BUS_MASTER_RLD manipulations
Instead of setting and clearing BUS_MASTER_RLD register on every C3 state enter/exit, set it only once if the system supports C3 state and we are going to "disable" bus master arbitration while in it. This is what Linux does for the past 14 years, and for even more time this register is not implemented in a relevant hardware. Same time since this is only a single bit in a bigger register, ACPI has to do take a global lock and do read-modify-write for it, that is too expensive, saved only by C3 not entered frequently, but enough to be seen in idle system CPU profiles. MFC after: 1 month (cherry picked from commit 5bc10feacc9d81e3bba9d28734a85e996682b408)
-rw-r--r--sys/dev/acpica/acpi_cpu.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index 395faf450188..1d5b93c304b0 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -512,6 +512,9 @@ static void
enable_idle(struct acpi_cpu_softc *sc)
{
+ if (sc->cpu_cx_count > sc->cpu_non_c3 + 1 &&
+ (cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0)
+ AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 1);
sc->cpu_disable_idle = FALSE;
}
@@ -1164,14 +1167,13 @@ acpi_cpu_idle(sbintime_t sbt)
}
/*
- * For C3, disable bus master arbitration and enable bus master wake
- * if BM control is available, otherwise flush the CPU cache.
+ * For C3, disable bus master arbitration if BM control is available.
+ * CPU may have to wake up to handle it. Otherwise flush the CPU cache.
*/
if (cx_next->type == ACPI_STATE_C3) {
- if ((cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) {
+ if ((cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0)
AcpiWriteBitRegister(ACPI_BITREG_ARB_DISABLE, 1);
- AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 1);
- } else
+ else
ACPI_FLUSH_CPU_CACHE();
}
@@ -1206,12 +1208,10 @@ acpi_cpu_idle(sbintime_t sbt)
else
end_ticks = cpu_ticks();
- /* Enable bus master arbitration and disable bus master wakeup. */
+ /* Enable bus master arbitration. */
if (cx_next->type == ACPI_STATE_C3 &&
- (cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) {
+ (cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0)
AcpiWriteBitRegister(ACPI_BITREG_ARB_DISABLE, 0);
- AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 0);
- }
ACPI_ENABLE_IRQS();
if (cx_next->type == ACPI_STATE_C3)