svn commit: r340170 - in head/sys: amd64/include i386/include x86/x86
John Baldwin
jhb at FreeBSD.org
Mon Nov 5 22:54:06 UTC 2018
Author: jhb
Date: Mon Nov 5 22:54:03 2018
New Revision: 340170
URL: https://svnweb.freebsd.org/changeset/base/340170
Log:
Add a custom implementation of cpu_lock_delay() for x86.
Avoid using DELAY() since it can try to use spin locks on CPUs without
a P-state invariant TSC. For cpu_lock_delay(), always use the TSC if
it exists (even if it is not P-state invariant) to delay for a
microsecond. If the TSC does not exist, read from I/O port 0x84 to
delay instead.
PR: 228768
Reported by: Roger Hammerstein <cheeky.m at live.com>
Reviewed by: kib
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D17851
Modified:
head/sys/amd64/include/cpu.h
head/sys/i386/include/cpu.h
head/sys/x86/x86/delay.c
Modified: head/sys/amd64/include/cpu.h
==============================================================================
--- head/sys/amd64/include/cpu.h Mon Nov 5 22:53:50 2018 (r340169)
+++ head/sys/amd64/include/cpu.h Mon Nov 5 22:54:03 2018 (r340170)
@@ -50,7 +50,6 @@
#define cpu_getstack(td) ((td)->td_frame->tf_rsp)
#define cpu_setstack(td, ap) ((td)->td_frame->tf_rsp = (ap))
#define cpu_spinwait() ia32_pause()
-#define cpu_lock_delay() DELAY(1)
#define TRAPF_USERMODE(framep) \
(ISPL((framep)->tf_cs) == SEL_UPL)
@@ -78,6 +77,7 @@ extern char etext[];
extern void (*vmm_resume_p)(void);
void cpu_halt(void);
+void cpu_lock_delay(void);
void cpu_reset(void);
void fork_trampoline(void);
void swi_vm(void *);
Modified: head/sys/i386/include/cpu.h
==============================================================================
--- head/sys/i386/include/cpu.h Mon Nov 5 22:53:50 2018 (r340169)
+++ head/sys/i386/include/cpu.h Mon Nov 5 22:54:03 2018 (r340170)
@@ -50,7 +50,6 @@
#define cpu_getstack(td) ((td)->td_frame->tf_esp)
#define cpu_setstack(td, ap) ((td)->td_frame->tf_esp = (ap))
#define cpu_spinwait() ia32_pause()
-#define cpu_lock_delay() DELAY(1)
#define TRAPF_USERMODE(framep) \
((ISPL((framep)->tf_cs) == SEL_UPL) || ((framep)->tf_eflags & PSL_VM))
@@ -73,6 +72,7 @@ extern char btext[];
extern char etext[];
void cpu_halt(void);
+void cpu_lock_delay(void);
void cpu_reset(void);
void fork_trampoline(void);
void swi_vm(void *);
Modified: head/sys/x86/x86/delay.c
==============================================================================
--- head/sys/x86/x86/delay.c Mon Nov 5 22:53:50 2018 (r340169)
+++ head/sys/x86/x86/delay.c Mon Nov 5 22:54:03 2018 (r340170)
@@ -122,3 +122,22 @@ DELAY(int n)
init_ops.early_delay(n);
TSEXIT();
}
+
+void
+cpu_lock_delay(void)
+{
+
+ /*
+ * Use TSC to wait for a usec if present, otherwise fall back
+ * to reading from port 0x84. We can't call into timecounters
+ * for this delay since timecounters might use spin locks.
+ *
+ * Note that unlike delay_tc(), this uses the TSC even if it
+ * is not P-state invariant. For this function it is ok to
+ * wait even a few usecs.
+ */
+ if (tsc_freq != 0)
+ delay_tsc(1);
+ else
+ inb(0x84);
+}
More information about the svn-src-all
mailing list