kernel/acpi_timer: Lower the bar for ACPI-fast on real and virtual machines.
authorSascha Wildner <saw@online.de>
Sun, 3 Aug 2014 02:27:51 +0000 (04:27 +0200)
committerSascha Wildner <saw@online.de>
Sun, 3 Aug 2014 02:27:51 +0000 (04:27 +0200)
This brings in FreeBSD's revisions 220331-220369:

r220369 | jkim | 2011-04-05 20:40:19 +0200 (Tue, 05 Apr 2011) | 6 lines

Lower the bar for ACPI-fast on real machines slightly.  Empirical evidences
show that there are perfectly working PM timers with occasional "hiccups",
probably because of an SMI.  Now we ignore the maximum if it happens once in
the test loop and the width is small enough.  Also, relax normal width a bit
to count in a boundary case.

------------------------------------------------------------------------
r220336 | jkim | 2011-04-04 19:44:26 +0200 (Mon, 04 Apr 2011) | 3 lines

Always check the current minimum value to make the test more predictable.
Use INT32_MAX instead of an arbitrary big number for the initial minimum.

------------------------------------------------------------------------
r220333 | jkim | 2011-04-04 19:00:50 +0200 (Mon, 04 Apr 2011) | 5 lines

Lower the bar for ACPI-fast on virtual machines.  The current logic depends
on the fact that real hardware has almost fixed cost to read the ACPI timer.
It is virtually always false for hardware emulation and it makes no sense to
read it multiple times, which is already quite expensive for full emulation.

------------------------------------------------------------------------
r220331 | jkim | 2011-04-04 18:47:42 +0200 (Mon, 04 Apr 2011) | 2 lines

Add inline to acpi_timer_read() to reduce unnecessary jumps and calls.

sys/dev/acpica/acpi_timer.c

index d316114..5db00dc 100644 (file)
@@ -105,7 +105,7 @@ static devclass_t acpi_timer_devclass;
 DRIVER_MODULE(acpi_timer, acpi, acpi_timer_driver, acpi_timer_devclass, NULL, NULL);
 MODULE_DEPEND(acpi_timer, acpi, 1, 1, 1);
 
-static u_int
+static inline uint32_t
 acpi_timer_read(void)
 {
     return (bus_space_read_4(acpi_timer_bst, acpi_timer_bsh, 0));
@@ -383,11 +383,11 @@ static int
 acpi_timer_test(void)
 {
     uint32_t   last, this;
-    int                min, max, n, delta;
+    int                min, max, max2, n, delta;
     register_t s;
 
-    min = 10000000;
-    max = 0;
+    min = INT32_MAX;
+    max = max2 = 0;
 
     /* Test the timer with interrupts disabled to get accurate results. */
 #if defined(__i386__)
@@ -402,9 +402,13 @@ acpi_timer_test(void)
     for (n = 0; n < 2000; n++) {
        this = acpi_timer_read();
        delta = acpi_TimerDelta(this, last);
-       if (delta > max)
+       if (delta > max) {
+           max2 = max;
            max = delta;
-       else if (delta < min)
+       } else if (delta > max2) {
+           max2 = delta;
+       }
+       if (delta < min)
            min = delta;
        last = this;
     }
@@ -416,9 +420,10 @@ acpi_timer_test(void)
 #error "no read_eflags"
 #endif
 
-    if (max - min > 2)
+    delta = max2 - min;
+    if ((max - min > 8 || delta > 3) && vmm_guest == VMM_GUEST_NONE)
        n = 0;
-    else if (min < 0 || max == 0)
+    else if (min < 0 || max == 0 || max2 == 0)
        n = 0;
     else
        n = 1;
@@ -430,4 +435,3 @@ acpi_timer_test(void)
 
     return (n);
 }
-