Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/amd64/mp_machdep.c
Show First 20 Lines • Show All 654 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
static void | static void | ||||
smp_targeted_tlb_shootdown(cpuset_t mask, pmap_t pmap, vm_offset_t addr1, | smp_targeted_tlb_shootdown(cpuset_t mask, pmap_t pmap, vm_offset_t addr1, | ||||
vm_offset_t addr2, smp_invl_cb_t curcpu_cb, enum invl_op_codes op) | vm_offset_t addr2, smp_invl_cb_t curcpu_cb, enum invl_op_codes op) | ||||
{ | { | ||||
cpuset_t other_cpus, mask1; | cpuset_t other_cpus, mask1; | ||||
uint32_t generation, *p_cpudone; | uint32_t generation, *p_cpudone; | ||||
int cpu; | int cpu; | ||||
bool is_all; | |||||
/* | /* | ||||
* It is not necessary to signal other CPUs while booting or | * It is not necessary to signal other CPUs while booting or | ||||
* when in the debugger. | * when in the debugger. | ||||
*/ | */ | ||||
if (kdb_active || KERNEL_PANICKED() || !smp_started) | if (kdb_active || KERNEL_PANICKED() || !smp_started) | ||||
goto local_cb; | goto local_cb; | ||||
KASSERT(curthread->td_pinned > 0, ("curthread not pinned")); | KASSERT(curthread->td_pinned > 0, ("curthread not pinned")); | ||||
/* | /* | ||||
* Check for other cpus. Return if none. | * Check for other cpus. Return if none. | ||||
*/ | */ | ||||
if (!CPU_CMP(&mask, &all_cpus)) { | is_all = !CPU_CMP(&mask, &all_cpus); | ||||
if (mp_ncpus <= 1) | |||||
goto local_cb; | |||||
} else { | |||||
CPU_CLR(PCPU_GET(cpuid), &mask); | CPU_CLR(PCPU_GET(cpuid), &mask); | ||||
if (CPU_EMPTY(&mask)) | if (CPU_EMPTY(&mask)) | ||||
goto local_cb; | goto local_cb; | ||||
} | |||||
/* | /* | ||||
* Initiator must have interrupts enabled, which prevents | * Initiator must have interrupts enabled, which prevents | ||||
* non-invalidation IPIs that take smp_ipi_mtx spinlock, | * non-invalidation IPIs that take smp_ipi_mtx spinlock, | ||||
* from deadlocking with us. On the other hand, preemption | * from deadlocking with us. On the other hand, preemption | ||||
* must be disabled to pin initiator to the instance of the | * must be disabled to pin initiator to the instance of the | ||||
* pcpu pc_smp_tlb data and scoreboard line. | * pcpu pc_smp_tlb data and scoreboard line. | ||||
*/ | */ | ||||
Show All 22 Lines | while ((cpu = CPU_FFS(&mask1)) != 0) { | ||||
*invl_scoreboard_slot(cpu) = 0; | *invl_scoreboard_slot(cpu) = 0; | ||||
} | } | ||||
/* | /* | ||||
* IPI acts as a fence between writing to the scoreboard above | * IPI acts as a fence between writing to the scoreboard above | ||||
* (zeroing slot) and reading from it below (wait for | * (zeroing slot) and reading from it below (wait for | ||||
* acknowledgment). | * acknowledgment). | ||||
*/ | */ | ||||
if (!CPU_CMP(&mask, &all_cpus)) { | if (is_all) { | ||||
ipi_all_but_self(IPI_INVLOP); | ipi_all_but_self(IPI_INVLOP); | ||||
other_cpus = all_cpus; | other_cpus = all_cpus; | ||||
CPU_CLR(PCPU_GET(cpuid), &other_cpus); | CPU_CLR(PCPU_GET(cpuid), &other_cpus); | ||||
} else { | } else { | ||||
other_cpus = mask; | other_cpus = mask; | ||||
ipi_selected(mask, IPI_INVLOP); | ipi_selected(mask, IPI_INVLOP); | ||||
} | } | ||||
curcpu_cb(pmap, addr1, addr2); | curcpu_cb(pmap, addr1, addr2); | ||||
▲ Show 20 Lines • Show All 419 Lines • Show Last 20 Lines |