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


Reply via email to