On 11/13/25 06:19, Zhao Liu wrote:
Enable lockless IO for HPET to allow BQL free MMIO access.
But BQL context is still needed for some cases during MMIO:
* IRQ handling:
Like C version of HPET did (commit d99041a20328 ("hpet: guard IRQ
handling with BQL"), BQL context is needed during IRQ handling.
But Rust HPET has an extra reason that InterruptSource is placed in
BqlCell, which requires BQL context explicitly. (This also shows
that the BQL limitation in the design of the InterruptSource binding
is reasonable.)
Thanks, this is helpful. It shows some complications that I honestly
hadn't thought about. So many more things to be precise about, compared
to C... but I have an idea which I'll mention below. :)
* BqlCell/BqlRefCell access.
Except InterruptSource, HPETState has other BqlCell and BqlRefCell:
hpet_offset (BqlCell<u64>), rtc_irq_level (BqlCell<u32>) and timers
([BqlRefCell<HPETTimer>; HPET_MAX_TIMERS]).
Their data may change during runtime, so the atomic context is
required.
I have already mentioned HPETTimer in the other email, but I would also
move hpet_offset to HPETRegisters if possible. It doesn't seem hard.
And as an aside, I wonder if you really need to pass MutexGuard and not
&mut HPETRegisters. Once you don't have BQL dependencies, you can just
remove the assert!(bql::is_locked()) without switching to MutexGuard<>.
In the meanwhile, even if they are not perfect (especially due to
migration), I think touching patches 1-19 further is too messy, so I'll
rebase on top of Stefan's tracing patches and push them to rust-next.
Let's start from there and I'll take a look tomorrow maybe on how to fix
migration. Migratable<HPETTimer> looks like a powerful tool for that.
Then the new problem is that we have to figure out a way to handle IRQs.
They are also messy for PL011 compared to the C version, and that will
make it possible to enable lockless IO.
The crazy idea that just came to mind, is a Latched<u32> that is
something like an (AtomicU32, BqlCell<u32>) tuple. Then we set the
individual bits outside the BQL and update IRQs at the end of the MMIO
in a bql::with_guard() block. Maybe if you have some time you can
prototype that for PL011 (even without generics, you could just do
LatchedU32 for a start)?
Paolo