linux/rust/kernel
Lyude Paul ec4fad7c2b rust: sync: Introduce SpinLockIrq::lock_with() and friends
`SpinLockIrq` and `SpinLock` use the exact same underlying C structure,
with the only real difference being that the former uses the
irq_disable() and irq_enable() variants for locking/unlocking. These
variants can introduce some minor overhead in contexts where we already
know that local processor interrupts are disabled, and as such we want a
way to be able to skip modifying processor interrupt state in said
contexts in order to avoid some overhead - just like the current C API
allows us to do.

In order to do this, we add some special functions for SpinLockIrq:
lock_with() and try_lock_with(), which allow acquiring the lock without
changing the interrupt state - as long as the caller can provide a
LocalInterruptDisabled reference to prove that local processor
interrupts have been disabled.

In some hacked-together benchmarks we ran, most of the time this did
actually seem to lead to a noticeable difference in overhead:

  From an aarch64 VM running on a MacBook M4:
    lock() when irq is disabled, 100 times cost Delta { nanos: 500 }
    lock_with() when irq is disabled, 100 times cost Delta { nanos: 292 }
    lock() when irq is enabled, 100 times cost Delta { nanos: 834 }

    lock() when irq is disabled, 100 times cost Delta { nanos: 459 }
    lock_with() when irq is disabled, 100 times cost Delta { nanos: 291 }
    lock() when irq is enabled, 100 times cost Delta { nanos: 709 }

  From an x86_64 VM (qemu/kvm) running on a i7-13700H
    lock() when irq is disabled, 100 times cost Delta { nanos: 1002 }
    lock_with() when irq is disabled, 100 times cost Delta { nanos: 729 }
    lock() when irq is enabled, 100 times cost Delta { nanos: 1516 }

    lock() when irq is disabled, 100 times cost Delta { nanos: 754 }
    lock_with() when irq is disabled, 100 times cost Delta { nanos: 966 }
    lock() when irq is enabled, 100 times cost Delta { nanos: 1227 }

    (note that there were some runs on x86_64 where lock() on irq
    disabled vs. lock_with() on irq disabled had equivalent benchmarks,
    but it very much appeared to be a minority of test runs.)

While it's not clear how this affects real-world workloads yet, let's
add this for the time being so we can find out.

This makes it so that a `SpinLockIrq` will work like a `SpinLock` if
interrupts are disabled. So a function:

        (&'a SpinLockIrq, &'a LocalInterruptDisabled) -> Guard<'a, .., SpinLockBackend>

makes sense. Note that due to `Guard` and `LocalInterruptDisabled`
having the same lifetime, interrupts cannot be enabled while the Guard
exists.

Signed-off-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Boqun Feng <boqun@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260807070218.27144-19-boqun@kernel.org
2026-08-10 12:53:11 +02:00
..
alloc Driver core changes for 7.2-rc1 2026-06-15 12:41:17 +05:30
block rust: block: fix GenDisk cleanup paths 2026-05-31 19:45:06 -06:00
debugfs Driver core changes for 7.0-rc1 2026-02-11 17:43:59 -08:00
device rust: device: replace kernel::c_str! with C-Strings 2025-12-22 17:30:24 +01:00
drm rust/drm/gem: Use DeviceContext with GEM objects 2026-06-02 22:51:16 +02:00
fs rust: fs: add file::Offset type alias 2025-11-05 00:05:38 +01:00
gpu rust: gpu: Add GPU buddy allocator bindings 2026-03-23 21:41:47 +01:00
interop rust: interop: Add list module for C linked list interface 2026-03-23 20:29:28 +01:00
io Driver core changes for 7.2-rc1 2026-06-15 12:41:17 +05:30
iommu rust: iommu: fix srctree link warning 2026-01-22 09:19:30 +01:00
irq rust: irq: move 'static bounds to traits 2026-03-03 20:33:26 +01:00
list Locking updates for v7.1: 2026-04-14 12:36:25 -07:00
mm mm: rename zap_page_range_single() to zap_vma_range() 2026-04-05 13:53:15 -07:00
net rust: make build_assert module the home of related macros 2026-06-10 09:07:13 +02:00
num rust: make build_assert module the home of related macros 2026-06-10 09:07:13 +02:00
pci rust: pci: make Bar lifetime-parameterized 2026-05-27 16:24:23 +02:00
ptr rust: ptr: remove implicit index projection syntax 2026-06-05 10:16:47 +02:00
str rust: str: add radix prefixed integer parsing functions 2025-11-03 14:40:45 +01:00
sync rust: sync: Introduce SpinLockIrq::lock_with() and friends 2026-08-10 12:53:11 +02:00
time hrtimer: add usage examples to documentation 2026-03-23 08:31:00 +01:00
types rust: types: add ForLt trait for higher-ranked lifetime support 2026-05-27 16:24:59 +02:00
.gitignore rust: Add warn_on macro 2025-07-23 02:05:58 +02:00
acpi.rs rust: acpi: replace core::mem::zeroed with pin_init::zeroed 2025-10-27 20:27:05 +01:00
alloc.rs rust: alloc: cleanup imports and use "kernel vertical" style 2026-05-20 17:34:17 +02:00
auxiliary.rs rust: auxiliary: generalize Registration over ForLt 2026-05-27 16:27:28 +02:00
bitfield.rs rust: bitfield: mark Debug impl as #[inline] 2026-06-17 01:32:56 +02:00
bitmap.rs rust: tests: add Kconfig for KUnit test 2026-06-08 02:30:33 +02:00
bits.rs rust: bits: always inline functions using build_assert with arguments 2026-01-18 20:40:11 +01:00
block.rs rust: block: add block related constants 2025-09-02 05:23:56 -06:00
bug.rs rust: bug: Support DEBUG_BUGVERBOSE_DETAILED option 2026-01-30 05:18:17 +01:00
build_assert.rs rust: make build_assert module the home of related macros 2026-06-10 09:07:13 +02:00
clk.rs rust: clk: implement Send and Sync 2026-04-03 11:57:35 +02:00
configfs.rs rust: configfs: replace kernel::c_str! with C-Strings 2026-01-15 09:26:49 +01:00
cpu.rs rust: kernel: cpu: mark CpuId::current() inline 2025-09-14 23:58:45 +02:00
cpufreq.rs Driver core changes for 7.2-rc1 2026-06-15 12:41:17 +05:30
cpumask.rs rust: cpumask: rename methods of Cpumask for clarity and consistency 2026-01-27 11:21:23 +05:30
cred.rs Char/Misc/IIO/Binder changes for 6.18-rc1 2025-10-04 16:26:32 -07:00
debugfs.rs rust: debugfs: Use kernel Atomic type in docs example 2026-01-19 15:02:46 +01:00
device_id.rs rust: device_id: replace incorrect word in safety documentation 2025-12-29 14:09:18 +01:00
device.rs rust: device: make Core and CoreInternal lifetime-parameterized 2026-05-27 16:22:42 +02:00
devres.rs rust: devres: add 'static bound to Devres<T> 2026-05-29 01:06:10 +02:00
dma.rs Driver core changes for 7.2-rc1 2026-06-15 12:41:17 +05:30
driver.rs Merge patch series "rust: device: Higher-Ranked Lifetime Types for device drivers" 2026-05-29 00:38:54 +02:00
error.rs rust: error: replace match + panic in const context with const expect 2026-05-28 11:08:27 +02:00
faux.rs rust: faux: use "kernel vertical" style for imports 2026-01-07 19:56:00 +01:00
firmware.rs rust: firmware: replace kernel::c_str! with C-Strings 2025-11-17 00:53:47 +01:00
fmt.rs rust: fmt: use vertical import style 2026-05-20 00:47:24 +02:00
fs.rs rust: fs: add Kiocb struct 2025-09-06 13:27:20 +02:00
generated_arch_reachable_asm.rs.S rust: Add warn_on macro 2025-07-23 02:05:58 +02:00
generated_arch_static_branch_asm.rs.S
generated_arch_warn_asm.rs.S rust: Add warn_on macro 2025-07-23 02:05:58 +02:00
gpu.rs rust: gpu: Add GPU buddy allocator bindings 2026-03-23 21:41:47 +01:00
i2c.rs Driver core changes for 7.2-rc1 2026-06-15 12:41:17 +05:30
id_pool.rs rust: id_pool: do not immediately acquire new ids 2025-12-02 14:17:09 -05:00
impl_flags.rs rust: add impl_flags! macro for defining common bitflag operations 2026-02-02 08:09:11 +01:00
init.rs rust: inline some init methods 2026-06-09 04:13:21 +02:00
interop.rs rust: interop: Add list module for C linked list interface 2026-03-23 20:29:28 +01:00
interrupt.rs rust: Introduce interrupt module 2026-08-10 12:53:09 +02:00
io.rs rust: io: introduce write_reg and LocatedRegister 2026-03-17 20:04:11 +01:00
ioctl.rs rust: make build_assert module the home of related macros 2026-06-10 09:07:13 +02:00
iov.rs rust: iov: add iov_iter abstractions for ITER_DEST 2025-09-06 13:27:20 +02:00
irq.rs rust: irq: add support for threaded IRQs and handlers 2025-08-12 20:22:09 +02:00
jump_label.rs
Kconfig.test rust: bitfield: Add KUnit tests for bitfield 2026-06-09 04:13:07 +02:00
kunit.rs rust: tests: add Kconfig for KUnit test 2026-06-08 02:30:33 +02:00
lib.rs rust: Introduce interrupt module 2026-08-10 12:53:09 +02:00
list.rs rust: list: hide macros from top-level kernel doc 2026-03-27 12:15:47 +01:00
maple_tree.rs rust: maple_tree: rcu_read_lock() in destructor to silence lockdep 2025-12-23 11:23:15 -08:00
miscdevice.rs rust: miscdevice: remove redundant imports 2026-05-23 13:47:32 +02:00
mm.rs rust: mm: update ARef and AlwaysRefCounted imports from sync::aref 2025-09-13 16:55:15 -07:00
module_param.rs rust: module_param: add missing newline to pr_warn_once 2026-06-04 16:42:34 +00:00
net.rs
num.rs rust: num: add Bounded integer wrapping type 2025-11-19 00:22:24 +01:00
of.rs rust: of: use core::ffi::CStr method names 2025-09-16 09:26:59 +02:00
opp.rs opp: rust: mark OPP methods as inline 2026-05-25 09:40:52 +05:30
page.rs mm.git review status for mm-hotfixes-stable..mm-stable 2026-06-19 10:14:34 -07:00
pci.rs rust: pci: make Driver trait lifetime-parameterized 2026-05-27 16:23:10 +02:00
pid_namespace.rs rust: pid_namespace: update AlwaysRefCounted imports from sync::aref 2025-08-19 13:08:41 +02:00
platform.rs driver core: platform: set mod_name in driver registration 2026-06-08 23:28:24 +02:00
prelude.rs rust: prelude: add zerocopy{,_derive}::IntoBytes 2026-06-17 00:32:42 +02:00
print.rs rust: print: Add pr_*_once macros 2026-01-30 05:47:05 +01:00
processor.rs rust: Add cpu_relax() helper 2025-08-21 16:58:07 +02:00
ptr.rs Rust timekeeping changes for v7.1 2026-04-08 10:44:11 +02:00
pwm.rs rust: pwm: Simplify to_result call sites and unsafe blocks 2026-01-20 18:49:58 +01:00
rbtree.rs Rust changes for v6.20 / v7.0 2026-02-10 11:53:01 -08:00
regulator.rs rust: regulator: do not assume that regulator_get() returns non-null 2026-03-24 13:08:21 +00:00
revocable.rs rust: revocable: Use LKMM atomics instead of Rust atomics 2026-08-04 05:52:54 -07:00
safety.rs rust: safety: introduce unsafe_precondition_assert! macro 2026-02-02 08:10:48 +01:00
scatterlist.rs rust: scatterlist: Update ARef imports to use sync::aref 2025-12-18 17:25:45 +01:00
security.rs rust_binder: add Rust Binder driver 2025-09-19 09:40:46 +02:00
seq_file.rs rust: seq_file: replace kernel::c_str! with C-Strings 2026-01-29 15:32:40 +01:00
sizes.rs rust: sizes: add SizeConstants trait for device address space constants 2026-04-07 12:57:50 +02:00
soc.rs rust: Add soc_device support 2025-12-28 12:43:56 +01:00
std_vendor.rs
str.rs rust: str: clean unused import for Rust >= 1.98 2026-06-10 09:07:13 +02:00
sync.rs rust: sync: Add SpinLockIrq 2026-08-10 12:53:10 +02:00
task.rs Char/Misc/IIO/and others driver updates for 7.1-rc1 2026-04-24 13:23:50 -07:00
time.rs rust: time: make ClockSource unsafe trait 2026-03-23 08:29:48 +01:00
tracepoint.rs
transmute.rs rust: transmute: simplify code with Rust 1.80.0 split_at_*checked() 2026-04-07 10:00:24 +02:00
types.rs rust: types: add ForLt trait for higher-ranked lifetime support 2026-05-27 16:24:59 +02:00
uaccess.rs Char/Misc/IIO/and others driver updates for 7.1-rc1 2026-04-24 13:23:50 -07:00
usb.rs rust: usb: make Driver trait lifetime-parameterized 2026-05-27 16:23:51 +02:00
workqueue.rs rust: workqueue: use new sync::aref path for imports 2026-03-26 15:45:34 +00:00
xarray.rs rust: make build_assert module the home of related macros 2026-06-10 09:07:13 +02:00