On 9/2/26 20:02, Philippe Mathieu-Daudé wrote:
On the other hand, if we do have the BQL in exec_halt
then why is the x86 implementation explicitly taking
the BQL when it calls apic_poll_irq()?
Trying harder, my understanding is apic_poll_irq() only requires
the BQL for the apic_update_irq() call, not apic_sync_vapic().
So maybe only apic_sync_vapic() belongs to process_async_events(),
leaving apic_update_irq() to transition_halt_to_exec().
Paolo does that sound like going in the good direction?
Unfortunately not, because apic_update_irq() is needed to call
cpu_interrupt() and break out of halt.
By the way... cpu_has_work_after_processing_async_events() is a bit
long, what about simply cpu_poll_while_halted()?
Answering Peter's question above, the way in which the code is protected
against the BQL is basically two-fold: 1) kicking the CPU out of
whatever it's doing, for example in tcg_handle_interrupt, 2) changing
what other conditions affect cpu_has_work() only in the vCPU thread,
e.g. with run_on_cpu.
Specifically for Arm, it does seem like e.g. cpu->power_state needs
qatomic_read/set, and arm_set_cpu_power_state() needs a qemu_cpu_kick().
The SEV helper already does it (though for clarity and paranoia it
would be appropriate to use qatomic_read/set more consistently).
Paolo
On the one hand, if we don't have the BQL in has_work and
exec_halt then we should be a lot more careful about how
we code them (e.g. use of the right kind of atomics, and
there's no way the call to do_interrupt_all() in the x86
exec_halt can be safe without the BQL, surely).