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
This commit is contained in:
Konstantin Belousov 2015-08-12 09:55:52 +00:00
parent 0e190a486f
commit f36f7c0bf8

View file

@ -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