diff options
author | jhb <jhb@FreeBSD.org> | 2010-08-06 15:36:59 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2010-08-06 15:36:59 +0000 |
commit | 19ddbf5c3845e0aaeed327e2be2f168e30013b63 (patch) | |
tree | 90823b92f30822fa8ac56ad8c70614f9aae1017a /sys/amd64/amd64/mp_machdep.c | |
parent | 57b610d580a3dd85aaac28dae65ce416f30c3f31 (diff) | |
download | FreeBSD-src-19ddbf5c3845e0aaeed327e2be2f168e30013b63.zip FreeBSD-src-19ddbf5c3845e0aaeed327e2be2f168e30013b63.tar.gz |
Add a new ipi_cpu() function to the MI IPI API that can be used to send an
IPI to a specific CPU by its cpuid. Replace calls to ipi_selected() that
constructed a mask for a single CPU with calls to ipi_cpu() instead. This
will matter more in the future when we transition from cpumask_t to
cpuset_t for CPU masks in which case building a CPU mask is more expensive.
Submitted by: peter, sbruno
Reviewed by: rookie
Obtained from: Yahoo! (x86)
MFC after: 1 month
Diffstat (limited to 'sys/amd64/amd64/mp_machdep.c')
-rw-r--r-- | sys/amd64/amd64/mp_machdep.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 22ad40a..64e9880 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -1239,15 +1239,51 @@ ipi_selected(cpumask_t cpus, u_int ipi) do { old_pending = cpu_ipi_pending[cpu]; new_pending = old_pending | bitmap; - } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu],old_pending, new_pending)); - + } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu], + old_pending, new_pending)); if (old_pending) continue; } - lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]); } +} + +/* + * send an IPI to a specific CPU. + */ +void +ipi_cpu(int cpu, u_int ipi) +{ + u_int bitmap = 0; + u_int old_pending; + u_int new_pending; + + if (IPI_IS_BITMAPED(ipi)) { + bitmap = 1 << ipi; + ipi = IPI_BITMAP_VECTOR; + } + /* + * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit + * of help in order to understand what is the source. + * Set the mask of receiving CPUs for this purpose. + */ + if (ipi == IPI_STOP_HARD) + atomic_set_int(&ipi_nmi_pending, 1 << cpu); + + CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi); + KASSERT(cpu_apic_ids[cpu] != -1, ("IPI to non-existent CPU %d", cpu)); + + if (bitmap) { + do { + old_pending = cpu_ipi_pending[cpu]; + new_pending = old_pending | bitmap; + } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu], + old_pending, new_pending)); + if (old_pending) + return; + } + lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]); } /* |