git: c3afa8d1884f - stable/12 - Change mwait_bm_avoidance use to match Linux.

Alexander Motin mav at FreeBSD.org
Wed Apr 7 00:31:47 UTC 2021


The branch stable/12 has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=c3afa8d1884fd4eaef0cecc1a009f1121ad3a11c

commit c3afa8d1884fd4eaef0cecc1a009f1121ad3a11c
Author:     Alexander Motin <mav at FreeBSD.org>
AuthorDate: 2021-03-08 22:57:46 +0000
Commit:     Alexander Motin <mav at FreeBSD.org>
CommitDate: 2021-04-07 00:31:38 +0000

    Change mwait_bm_avoidance use to match Linux.
    
    Even though the information is very limited, it seems the intent of
    this flag is to control ACPI_BITREG_BUS_MASTER_STATUS use for C3,
    not force ACPI_BITREG_ARB_DISABLE manipulations for C2, where it was
    never needed, and which register not really doing anything for years.
    It wasted lots of CPU time on congested global ACPI hardware lock
    when many CPU cores were trying to enter/exit deep C-states same time.
    
    On idle 80-core system it pushed ping localhost latency up to 20ms,
    since badport_bandlim() via counter_ratecheck() wakes up all CPUs
    same time once a second just to synchronously reset the counters.
    Now enabling C-states increases the latency from 0.1 to just 0.25ms.
    
    Discussed with: kib
    MFC after:      1 month
    
    (cherry picked from commit 455219675dbd61010e180cacdfed51e7e34111e1)
---
 sys/dev/acpica/acpi_cpu.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index 4d7573d9b7d2..94f5b981b3c1 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -1155,17 +1155,19 @@ acpi_cpu_idle(sbintime_t sbt)
      * driver polling for new devices keeps this bit set all the
      * time if USB is loaded.
      */
+    cx_next = &sc->cpu_cx_states[cx_next_idx];
     if ((cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0 &&
-	cx_next_idx > sc->cpu_non_c3) {
+	cx_next_idx > sc->cpu_non_c3 &&
+	(!cx_next->do_mwait || cx_next->mwait_bm_avoidance)) {
 	status = AcpiReadBitRegister(ACPI_BITREG_BUS_MASTER_STATUS, &bm_active);
 	if (ACPI_SUCCESS(status) && bm_active != 0) {
 	    AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_STATUS, 1);
 	    cx_next_idx = sc->cpu_non_c3;
+	    cx_next = &sc->cpu_cx_states[cx_next_idx];
 	}
     }
 
     /* Select the next state and update statistics. */
-    cx_next = &sc->cpu_cx_states[cx_next_idx];
     sc->cpu_cx_stats[cx_next_idx]++;
     KASSERT(cx_next->type != ACPI_STATE_C0, ("acpi_cpu_idle: C0 sleep"));
 
@@ -1199,7 +1201,7 @@ 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.
      */
-    if (cx_next->type == ACPI_STATE_C3 || cx_next->mwait_bm_avoidance) {
+    if (cx_next->type == ACPI_STATE_C3) {
 	if ((cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) {
 	    AcpiWriteBitRegister(ACPI_BITREG_ARB_DISABLE, 1);
 	    AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 1);
@@ -1239,7 +1241,7 @@ acpi_cpu_idle(sbintime_t sbt)
 	end_time = ((cpu_ticks() - cputicks) << 20) / cpu_tickrate();
 
     /* Enable bus master arbitration and disable bus master wakeup. */
-    if ((cx_next->type == ACPI_STATE_C3 || cx_next->mwait_bm_avoidance) &&
+    if (cx_next->type == ACPI_STATE_C3 &&
       (cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) {
 	AcpiWriteBitRegister(ACPI_BITREG_ARB_DISABLE, 0);
 	AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 0);


More information about the dev-commits-src-all mailing list