| 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | |
| 3 | //! Interrupt controls |
| 4 | //! |
| 5 | //! This module allows Rust code to annotate areas of code where local processor interrupts should |
| 6 | //! be disabled, along with actually disabling local processor interrupts. |
| 7 | //! |
| 8 | //! # ⚠️ Warning! ⚠️ |
| 9 | //! |
| 10 | //! The usage of this module can be more complicated than meets the eye, especially surrounding |
| 11 | //! [preemptible kernels]. It's recommended to take care when using the functions and types defined |
| 12 | //! here and familiarize yourself with the various documentation we have before using them, along |
| 13 | //! with the various documents we link to here. |
| 14 | //! |
| 15 | //! # Reading material |
| 16 | //! |
| 17 | //! - [Software interrupts and realtime (LWN)](https://lwn.net/Articles/520076) |
| 18 | //! |
| 19 | //! [preemptible kernels]: https://www.kernel.org/doc/html/latest/locking/preempt-locking.html |
| 20 | |
| 21 | use crateNotThreadSafe; |
| 22 | |
| 23 | /// A guard that represents local processor interrupt disablement on preemptible kernels. |
| 24 | /// |
| 25 | /// [`LocalInterruptDisabled`] is a guard type that represents that local processor interrupts have |
| 26 | /// been disabled on a preemptible kernel. |
| 27 | /// |
| 28 | /// Certain functions take an immutable reference of [`LocalInterruptDisabled`] in order to require |
| 29 | /// that they may only be run in local-interrupt-disabled contexts on preemptible kernels. |
| 30 | /// |
| 31 | /// This is a marker type; it has no size, and is simply used as a compile-time guarantee that local |
| 32 | /// processor interrupts are disabled on preemptible kernels. Note that no guarantees about the |
| 33 | /// state of interrupts are made by this type on non-preemptible kernels. |
| 34 | /// |
| 35 | /// # Invariants |
| 36 | /// |
| 37 | /// Local processor interrupts are disabled on preemptible kernels for as long as an object of this |
| 38 | /// type exists. |
| 39 | ; |
| 40 | |
| 41 | /// Disable local processor interrupts on a preemptible kernel. |
| 42 | /// |
| 43 | /// This function disables local processor interrupts on a preemptible kernel, and returns a |
| 44 | /// [`LocalInterruptDisabled`] token as proof of this. On non-preemptible kernels, this function is |
| 45 | /// a no-op. |
| 46 | /// |
| 47 | /// **Usage of this function is discouraged** unless you are absolutely sure you know what you are |
| 48 | /// doing, as kernel interfaces for Rust that deal with interrupt state will typically handle local |
| 49 | /// processor interrupt state management on their own and managing this by hand is quite error |
| 50 | /// prone. |
| 51 | |
| 52 | |
| 53 | // SAFETY: It's always safe to call `local_interrupt_disable()`. |
| 54 | unsafe ; |
| 55 | |
| 56 | LocalInterruptDisabled |
| 57 | |
| 58 | |
| 59 | |
| 60 | |
| 61 | |
| 62 | // SAFETY: Per type invariants, a `local_interrupt_disable()` must be called to create this |
| 63 | // object, hence calling the corresponding `local_interrupt_enable()` is safe. |
| 64 | unsafe ; |
| 65 | |
| 66 | |
| 67 | |
| 68 | |
| 69 | /// Assume that local processor interrupts are disabled on preemptible kernels. |
| 70 | /// |
| 71 | /// This can be used for annotating code that is known to be run in contexts where local |
| 72 | /// processor interrupts are disabled on preemptible kernels. It makes no changes to the local |
| 73 | /// interrupt state on its own. |
| 74 | /// |
| 75 | /// # Safety |
| 76 | /// |
| 77 | /// For the whole life `'a`, local interrupts must be disabled on preemptible kernels. This |
| 78 | /// could be a context like, for example, an interrupt handler. |
| 79 | |
| 80 | pub unsafe |
| 81 | const ASSUME_DISABLED: &LocalInterruptDisabled = &LocalInterruptDisabled; |
| 82 | |
| 83 | // Confirm they're actually disabled if lockdep is available |
| 84 | // SAFETY: It's always safe to call `lockdep_assert_irqs_disabled()`. |
| 85 | unsafe ; |
| 86 | |
| 87 | ASSUME_DISABLED |
| 88 | |
| 89 |