All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@gmail.com>
To: Dirk Behme <dirk.behme@gmail.com>
Cc: "Dirk Behme" <dirk.behme@de.bosch.com>,
	"Lyude Paul" <lyude@redhat.com>,
	rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Danilo Krummrich" <dakr@redhat.com>,
	airlied@redhat.com, "Ingo Molnar" <mingo@redhat.com>,
	"Will Deacon" <will@kernel.org>,
	"Waiman Long" <longman@redhat.com>,
	"Peter Zijlstra" <peterz@infradead.org>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Andreas Hindborg" <a.hindborg@samsung.com>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"FUJITA Tomonori" <fujita.tomonori@gmail.com>,
	"Aakash Sen Sharma" <aakashsensharma@gmail.com>,
	"Valentin Obst" <kernel@valentinobst.de>
Subject: Re: [PATCH v3 1/3] rust: Introduce irq module
Date: Mon, 26 Aug 2024 08:34:42 -0700	[thread overview]
Message-ID: <Zsygkunml0DHWIX7@boqun-archlinux> (raw)
In-Reply-To: <afa6d33a-c933-4996-8cdf-e1677772d63e@gmail.com>

On Mon, Aug 26, 2024 at 04:59:45PM +0200, Dirk Behme wrote:
> Am 26.08.24 um 16:21 schrieb Boqun Feng:
> > On Mon, Aug 26, 2024 at 01:21:17PM +0200, Dirk Behme wrote:
> > > Hi Lyude,
> > > 
> > > On 02.08.2024 02:10, Lyude Paul wrote:
> > > > This introduces a module for dealing with interrupt-disabled contexts,
> > > > including the ability to enable and disable interrupts
> > > > (with_irqs_disabled()) - along with the ability to annotate functions as
> > > > expecting that IRQs are already disabled on the local CPU.
> > > > 
> > > > Signed-off-by: Lyude Paul <lyude@redhat.com>
> > > ...
> > > > diff --git a/rust/kernel/irq.rs b/rust/kernel/irq.rs
> > > > new file mode 100644
> > > > index 0000000000000..b52f8073e5cd0
> > > > --- /dev/null
> > > > +++ b/rust/kernel/irq.rs
> > > > @@ -0,0 +1,84 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +
> > > > +//! Interrupt controls
> > > > +//!
> > > > +//! This module allows Rust code to control processor interrupts. [`with_irqs_disabled()`] may be
> > > > +//! used for nested disables of interrupts, whereas [`IrqDisabled`] can be used for annotating code
> > > > +//! that requires interrupts to be disabled.
> > > > +
> > > > +use bindings;
> > > > +use core::marker::*;
> > > > +
> > > > +/// A token that is only available in contexts where IRQs are disabled.
> > > > +///
> > > > +/// [`IrqDisabled`] is marker made available when interrupts are not active. Certain functions take
> > > > +/// an [`IrqDisabled`] in order to indicate that they may only be run in IRQ-free contexts.
> > > > +///
> > > > +/// This is a marker type; it has no size, and is simply used as a compile-time guarantee that
> > > > +/// interrupts are disabled where required.
> > > > +///
> > > > +/// This token can be created by [`with_irqs_disabled`]. See [`with_irqs_disabled`] for examples and
> > > > +/// further information.
> > > > +#[derive(Copy, Clone, Debug, Ord, Eq, PartialOrd, PartialEq, Hash)]
> > > > +pub struct IrqDisabled<'a>(PhantomData<(&'a (), *mut ())>);
> > > > +
> > > > +impl IrqDisabled<'_> {
> > > > +    /// Create a new [`IrqDisabled`] without disabling interrupts.
> > > > +    ///
> > > > +    /// This creates an [`IrqDisabled`] token, which can be passed to functions that must be run
> > > > +    /// without interrupts. If debug assertions are enabled, this function will assert that
> > > > +    /// interrupts are disabled upon creation. Otherwise, it has no size or cost at runtime.
> > > > +    ///
> > > > +    /// # Panics
> > > > +    ///
> > > > +    /// If debug assertions are enabled, this function will panic if interrupts are not disabled
> > > > +    /// upon creation.
> > > > +    ///
> > > > +    /// # Safety
> > > > +    ///
> > > > +    /// This function must only be called in contexts where it is already known that interrupts have
> > > > +    /// been disabled for the current CPU, as the user is making a promise that they will remain
> > > > +    /// disabled at least until this [`IrqDisabled`] is dropped.
> > > > +    pub unsafe fn new() -> Self {
> > > > +        // SAFETY: FFI call with no special requirements
> > > > +        debug_assert!(unsafe { bindings::irqs_disabled() });
> > > > +
> > > > +        Self(PhantomData)
> > > > +    }
> > > > +}
> > > 
> > > I have some (understanding) questions for this IrqDisabled::new():
> > > 
> > > 1. It looks to me that both examples, below in this file irq.rs nor the
> > > with_irqs_disabled() example in spinlock.rs in the 3rd patch seem to use
> > > IrqDisabled::new()? At least some debug pr_info() added here doesn't print
> > > anything.
> > > 
> > > What's the intended use case of IrqDisabled::new()? Do we have any example?
> > > 
> > > I 'simulated' an interrupt handler where we know the interrupts are
> > > disabled:
> > > 
> > > let flags = unsafe { bindings::local_irq_save() }; // Simulate IRQ disable
> > > of an interrupt handler
> > > let mut g = foo.lock_with(unsafe {IrqDisabled::new() });
> > > g.val = 42;
> > > unsafe { bindings::local_irq_restore(flags) }; // Simulate IRQ re-enable of
> > > an interrupt handler
> > > 
> > > Is this the intended use case?
> > > 
> > > 
> > > 2. If the example above is what is intended here, is it intended that this
> > > has to be called unsafe{}?
> > > 
> > > foo.lock_with(unsafe {IrqDisabled::new() });
> > > 
> > > 
> > > 3. I somehow feel slightly uncomfortable with the debug_assert!().
> > > 
> > > I understood that this is intended to be not in production code and only
> > > enabled with RUST_DEBUG_ASSERTIONS for performance reasons? But I have some
> > > doubts how many people have RUST_DEBUG_ASSERTIONS enabled? And disable it
> > > for the production build?
> > > 
> > > Wouldn't it be better to be on the safe side and have this check, always?
> > 
> > No, for example in your code example above, the IRQ is knon being
> > disabled, so actually there's no point to check. The checking of course
> > makes sense in a function where there is no IRQ	disable code, and you
> > want to make sure it's only called when IRQ disabled. But that's
> > something you want to make sure at development time rather than in the
> > production.
> 
> I think I'm thinking the other way around ;)
> 
> Make sure I get a warning if I'm (as the developer) have done anything wrong
> in my assumption about the interrupt state my code is running with.
> 
> So cover the human failure case.
> 

Again, if a developer wants to find whether the code is correct or now,
that falls into the debugging catagory. If you want to know that, you
just enable the debug_assert!().

> 
> > > Wouldn't a permanent if statement checking this be safer for all cases?
> > 
> > I don't think so, it's just a checking, even if we enable this in the
> > production, the best it could do is just telling us the code is
> > incorrect.
> 
> Yes, exactly, this is what I'm looking for. Isn't this what the C's
> WARN_ONCE() & friends are about? Let the machine tell us that the programmer
> has done something wrong :)
> 

Not really, sometimes they are used to tell users that there are
hardware issues. But moreover, they are used to catch unexpected cases,
which as I mention above, not all the IRQ-disabled usages need this.

Regards,
Boqun

> 
> > If one realy wants to make sure a function works in both IRQ
> > disabled and enabled cases, he/she should check the irq status and
> > handle it accordingly
> 
> No, this is not what I'm looking for. I'm just about noticing the
> programming error case.
> 
> Best regards
> 
> Dirk
> 
> 
> > e.g.
> > 
> > 	if (irqs_disabled()) {
> > 		// irq is disabled, we can call it directly
> > 		do_sth();
> > 	} else {
> > 		// Disable IRQ on our own.
> > 		local_irq_disable();
> > 		do_sth();
> > 		local_irq_enabled();
> > 	}
> > 
> > > Compare e.g. BUG_ON() or WARN_ONCE() or similar in the kernel's C code?
> > > 
> > > Or could we invent anything more clever?
> > > 
> > 
> > I'm open to any new idea, but for the time being, I think the
> > debug_assert!() makes more sense.
> > 
> > Regards,
> > Boqun
> > 
> > > 
> > [...]
> > 
> 

  reply	other threads:[~2024-08-26 15:35 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-02  0:09 [PATCH v3 0/3] rust: Add irq abstraction, SpinLockIrq Lyude Paul
2024-08-02  0:10 ` [PATCH v3 1/3] rust: Introduce irq module Lyude Paul
2024-08-14 17:10   ` Boqun Feng
2024-08-14 17:35   ` Boqun Feng
2024-08-14 19:38     ` Lyude Paul
2024-08-14 20:17       ` Boqun Feng
2024-08-14 20:44         ` Benno Lossin
2024-08-14 20:57           ` Boqun Feng
2024-08-15  4:53             ` Boqun Feng
2024-08-15  6:40               ` Benno Lossin
2024-08-15 16:02                 ` Boqun Feng
2024-08-15 21:05                   ` Lyude Paul
2024-08-15 21:31                     ` Lyude Paul
2024-08-15 21:46                       ` Benno Lossin
2024-08-15 22:13                         ` Lyude Paul
2024-08-16 15:28                           ` Boqun Feng
2024-08-15 21:41                     ` Benno Lossin
2024-08-15 21:43                       ` Lyude Paul
2024-08-15 20:31         ` Lyude Paul
2024-08-15 21:48           ` Benno Lossin
2024-08-26 11:21   ` Dirk Behme
2024-08-26 14:21     ` Boqun Feng
2024-08-26 14:59       ` Dirk Behme
2024-08-26 15:34         ` Boqun Feng [this message]
2024-08-02  0:10 ` [PATCH v3 2/3] rust: sync: Introduce lock::Backend::Context Lyude Paul
2024-08-20 10:26   ` Dirk Behme
2024-08-02  0:10 ` [PATCH v3 3/3] rust: sync: Add SpinLockIrq Lyude Paul
2024-08-13 20:26 ` [PATCH v3 0/3] rust: Add irq abstraction, SpinLockIrq Lyude Paul

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Zsygkunml0DHWIX7@boqun-archlinux \
    --to=boqun.feng@gmail.com \
    --cc=a.hindborg@samsung.com \
    --cc=aakashsensharma@gmail.com \
    --cc=airlied@redhat.com \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=dakr@redhat.com \
    --cc=dirk.behme@de.bosch.com \
    --cc=dirk.behme@gmail.com \
    --cc=fujita.tomonori@gmail.com \
    --cc=gary@garyguo.net \
    --cc=kernel@valentinobst.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=lyude@redhat.com \
    --cc=mingo@redhat.com \
    --cc=ojeda@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=wedsonaf@gmail.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.