edu: add smp_mb__after_rmw()
Ensure ordering between clearing the COMPUTING flag and checking IRQFACT, and between setting the IRQFACT flag and checking COMPUTING. This ensures that no wakeups are lost. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: David Hildenbrand <david@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
6c5df4b48f
commit
2482aeea41
@ -267,6 +267,8 @@ static void edu_mmio_write(void *opaque, hwaddr addr, uint64_t val,
|
|||||||
case 0x20:
|
case 0x20:
|
||||||
if (val & EDU_STATUS_IRQFACT) {
|
if (val & EDU_STATUS_IRQFACT) {
|
||||||
qatomic_or(&edu->status, EDU_STATUS_IRQFACT);
|
qatomic_or(&edu->status, EDU_STATUS_IRQFACT);
|
||||||
|
/* Order check of the COMPUTING flag after setting IRQFACT. */
|
||||||
|
smp_mb__after_rmw();
|
||||||
} else {
|
} else {
|
||||||
qatomic_and(&edu->status, ~EDU_STATUS_IRQFACT);
|
qatomic_and(&edu->status, ~EDU_STATUS_IRQFACT);
|
||||||
}
|
}
|
||||||
@ -349,6 +351,9 @@ static void *edu_fact_thread(void *opaque)
|
|||||||
qemu_mutex_unlock(&edu->thr_mutex);
|
qemu_mutex_unlock(&edu->thr_mutex);
|
||||||
qatomic_and(&edu->status, ~EDU_STATUS_COMPUTING);
|
qatomic_and(&edu->status, ~EDU_STATUS_COMPUTING);
|
||||||
|
|
||||||
|
/* Clear COMPUTING flag before checking IRQFACT. */
|
||||||
|
smp_mb__after_rmw();
|
||||||
|
|
||||||
if (qatomic_read(&edu->status) & EDU_STATUS_IRQFACT) {
|
if (qatomic_read(&edu->status) & EDU_STATUS_IRQFACT) {
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
edu_raise_irq(edu, FACT_IRQ);
|
edu_raise_irq(edu, FACT_IRQ);
|
||||||
|
Loading…
Reference in New Issue
Block a user