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@live.com> Reviewed by: kib MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D17851
This commit is contained in:
parent
f497acb46a
commit
ed96335a07
@ -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 *);
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user