summaryrefslogtreecommitdiffstats
path: root/sys/x86
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-08-12 09:55:52 +0000
committerkib <kib@FreeBSD.org>2015-08-12 09:55:52 +0000
commit897bebb89d576a4769b1b67f7529a5eb5d1bb0ad (patch)
tree65a8b833c40155048f0bbd7a03e0fe8b09608093 /sys/x86
parent9458aa2b576bc8a0820858af28632bcabebd4a48 (diff)
downloadFreeBSD-src-897bebb89d576a4769b1b67f7529a5eb5d1bb0ad.zip
FreeBSD-src-897bebb89d576a4769b1b67f7529a5eb5d1bb0ad.tar.gz
In x2APIC mode, IPI generation is atomic because it is performed by
single ICR MSR write. This is in contrast with the xAPIC mode, where we must read current ICR value, do bit fiddling and perform two 32-bit register writes. As a consequence, there is no need to disable interrupts around ICR value calculation and write. Note that typical users of ipi_raw() and ipi_vectored() take spinlock, which already disables interrupts. For them, the change removes unneeded CLI and POPFL/Q instructions. Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
Diffstat (limited to 'sys/x86')
-rw-r--r--sys/x86/x86/local_apic.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index cf2114d..8198971 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -1657,9 +1657,10 @@ native_lapic_ipi_raw(register_t icrlo, u_int dest)
("%s: reserved bits set in ICR LO register", __func__));
/* Set destination in ICR HI register if it is being used. */
- saveintr = intr_disable();
- if (!x2apic_mode)
+ if (!x2apic_mode) {
+ saveintr = intr_disable();
icr = lapic_read_icr();
+ }
if ((icrlo & APIC_DEST_MASK) == APIC_DEST_DESTFLD) {
if (x2apic_mode) {
@@ -1682,7 +1683,8 @@ native_lapic_ipi_raw(register_t icrlo, u_int dest)
vlo |= icrlo;
}
lapic_write_icr(vhi, vlo);
- intr_restore(saveintr);
+ if (!x2apic_mode)
+ intr_restore(saveintr);
}
#define BEFORE_SPIN 50000
OpenPOWER on IntegriCloud