Re: [PATCH v3 1/3] rust: Introduce irq module
From: Boqun Feng <hidden>
Date: 2024-08-14 17:46:20
Also in:
lkml
On Thu, Aug 01, 2024 at 08:10:00PM -0400, Lyude Paul wrote: [...]
+/// Run the closure `cb` with interrupts disabled on the local CPU.
+///
+/// This creates an [`IrqDisabled`] token, which can be passed to functions that must be run
+/// without interrupts.
+///
+/// # Examples
+///
+/// Using [`with_irqs_disabled`] to call a function that can only be called with interrupts
+/// disabled:
+///
+/// ```
+/// use kernel::irq::{IrqDisabled, with_irqs_disabled};
+///
+/// // Requiring interrupts be disabled to call a function
+/// fn dont_interrupt_me(_irq: IrqDisabled<'_>) {
+/// /* When this token is available, IRQs are known to be disabled. Actions that rely on this
+/// * can be safely performed
+/// */
+/// }
+///
+/// // Disabling interrupts. They'll be re-enabled once this closure completes.
+/// with_irqs_disabled(|irq| dont_interrupt_me(irq));
+/// ```
+#[inline]
+pub fn with_irqs_disabled<T>(cb: impl for<'a> FnOnce(IrqDisabled<'a>) -> T) -> T {
Given the current signature, can `cb` return with interrupts enabled (if
it re-enables interrupt itself)? For example:
with_irqs_disabled(|irq_disabled| {
// maybe a unsafe function.
reenable_irq(irq_disabled);
})
note that `cb` is a `-> T` function, other than `-> (IrqDisabled<'a>,
T)`, so semantically, it doesn't require IRQ still disabled after
return.
Regards,
Boqun
quoted hunk ↗ jump to hunk
+ // SAFETY: FFI call with no special requirements + let flags = unsafe { bindings::local_irq_save() }; + + let ret = cb(IrqDisabled(PhantomData)); + + // SAFETY: `flags` comes from our previous call to local_irq_save + unsafe { bindings::local_irq_restore(flags) }; + + ret +}diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 274bdc1b0a824..ead3a7ca5ba11 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs@@ -36,6 +36,7 @@ pub mod firmware; pub mod init; pub mod ioctl; +pub mod irq; #[cfg(CONFIG_KUNIT)] pub mod kunit; #[cfg(CONFIG_NET)]-- 2.45.2