mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Boqun Feng <boqun@kernel.org>
To: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: paulmck@kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/2] hazptr: Introduce CONFIG_HAZPTR_DEBUG misuse detection
Date: Thu, 9 Jul 2026 16:57:31 -0700	[thread overview]
Message-ID: <alA1a8eMZQ0eli4T@tardis.local> (raw)
In-Reply-To: <2d801522-6a77-47ad-8daf-d23cc85cbb7a@efficios.com>

On Thu, Jul 09, 2026 at 07:22:18PM -0400, Mathieu Desnoyers wrote:
> On 2026-07-09 19:05, Paul E. McKenney wrote:
> > On Thu, Jul 09, 2026 at 05:47:00PM -0400, Mathieu Desnoyers wrote:
> [...]
> > > > + */
> > > >    static inline
> > > >    void hazptr_detach_from_task(struct hazptr_ctx *ctx)
> > > >    {
> > > > @@ -160,17 +178,29 @@ void hazptr_note_context_switch(void)
> > > >    	}
> > > >    }
> > > > -/*
> > > > - * hazptr_acquire: Load pointer at address and protect with hazard pointer.
> > > > +/**
> > > > + * hazptr_acquire - Load pointer at address and protect with hazard pointer.
> > > > + *
> > > > + * @ctx: The hazard-pointer context to be passed to hazptr_release().
> > > > + * @addr_p: Pointer to the pointer that is to be hazard-pointer protected.
> > > >     *
> > > >     * Load @addr_p, and protect the loaded pointer with hazard pointer.
> > > > - * When using hazptr_acquire from interrupt handlers, the acquired slots
> > > > - * need to be released before returning from the interrupt handler.
> > > 
> > > I see that you removed wording of a major constraint here which allowed
> > > use of hazptr locally in a interrupt handler: the need to pair the
> > > acquire/release within the handler.
> > 
> > I did indeed remove that wording.  You could do something like this:
> > 
> > 	Task Context			IRQ Handler Interrupts Task
> > 	------------			---------------------------
> > 	preempt_disable();
> > 	ihp = __this_cpu_read(irq_hc);	ihp = __this_cpu_read(irq_hc);
> > 					p = hazptr_acquire(ihp, &gp);
> > 	lp = xchg(p, NULL);
> > 	if (lp) {
> > 		do_something(lp);
> > 		hazptr_release(ihp, lp);
> > 	}
> > 	preempt_enable();
> > 
> > If I understand the rules correctly (ha!), this is perfectly legal
> > and does not require a hazptr_detach_from_task().
> > 
> I am concerned about it, because I knowingly just used preempt disable
> to protect hazptr_acquire from the scheduler, but not from interrupt
> handlers, because it's faster than irqoff.
> 
> I am concerned that this use of hazptr_acquire could confuse the
> thread-level hazptr_acquire, let's dig:
> 
> void *hazptr_acquire(struct hazptr_ctx *ctx, void * const *addr_p)
> {
>         struct hazptr_percpu_slots *percpu_slots;
>         struct hazptr_slot_item *slot_item;
>         struct hazptr_slot *slot;
>         void *addr;
> 
>         guard(preempt)();
>         percpu_slots = this_cpu_ptr(&hazptr_percpu_slots);
>         slot_item = &percpu_slots->items[0];
>         slot = &slot_item->slot;
> [...]
> 
>   from here --------------------
>         if (unlikely(slot->addr))
>                 return __hazptr_acquire(ctx, addr_p);
>         WRITE_ONCE(slot->addr, HAZPTR_WILDCARD);        /* Store B */
> 
>         /* Memory ordering: Store B before Load A. */
>         smp_mb();
> 
>         /*
>          * Load @addr_p after storing wildcard to the hazard pointer slot.
>          */
>         addr = READ_ONCE(*addr_p);      /* Load A */
> 
>         /*
>          * We don't care about ordering of Store C. It will simply
>          * replace the wildcard by a more specific address. If addr is
>          * NULL, we simply store NULL into the slot.
>          */
>         WRITE_ONCE(slot->addr, addr);   /* Store C */
>    to here ----------------------------
> 
> I designed hazptr_acquire so a _nested_ interrupt which _brings back_
> the slot addr to its original state will work. Now let's see if
> that's still OK if the interrupt handler leaves the slot->addr
> populated with an address.
> 
> And no. If the interrupt happens right before "Store B", its
> reserved slot address is overwritten by the thread. That's incorrect.
> 
> So as it is today, the irq handler needs to vacate the slot before it
> returns, either through a hazptr release or a detach.
> 
> That being said, this is the code as it is today. If someone finds a
> clever way to support this use-case and keep it fast and not too complex,
> I'm all ears! :)
> 

I don't find this use-case is very useful, but I guess a different set
of percpu slot for interrupts can resolve this issue?

Regards,
Boqun

> One possible way to make it work would be to install the HAZPTR_WILDCARD
> with a local-cmpxchg expecting a NULL slot->addr. This would close this
> race window. But it comes at a non-null overhead price. Another alternative
> on x86 would be to use a lock prefixed cmpxchg, which has an implied smp_mb
> on success, which may be in the same ballpark as the sequence of WRITE_ONCE+
> explicit smp_mb().
> 
> Thanks,
> 
> Mathieu
> 
> -- 
> Mathieu Desnoyers
> EfficiOS Inc.
> https://www.efficios.com

  parent reply	other threads:[~2026-07-09 23:57 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-09 18:29 [PATCH 1/2] hazptrtorture: Fix hazptr ownership issue Mathieu Desnoyers
2026-07-09 18:29 ` [PATCH 2/2] hazptr: Introduce CONFIG_HAZPTR_DEBUG misuse detection Mathieu Desnoyers
2026-07-09 18:47   ` Paul E. McKenney
2026-07-09 18:56     ` Mathieu Desnoyers
2026-07-09 20:44       ` Paul E. McKenney
2026-07-09 21:47         ` Mathieu Desnoyers
2026-07-09 23:05           ` Paul E. McKenney
2026-07-09 23:22             ` Mathieu Desnoyers
2026-07-09 23:48               ` Paul E. McKenney
2026-07-10  0:10                 ` Mathieu Desnoyers
2026-07-10 19:07                   ` Paul E. McKenney
2026-07-11 13:48                     ` Mathieu Desnoyers
2026-07-11 23:55                       ` Paul E. McKenney
2026-07-14 19:16                         ` Mathieu Desnoyers
2026-07-14 20:54                           ` Paul E. McKenney
2026-07-14 21:06                             ` Mathieu Desnoyers
2026-07-14 21:31                               ` Paul E. McKenney
2026-07-09 23:57               ` Boqun Feng [this message]
2026-07-10  0:03                 ` Mathieu Desnoyers
2026-07-09 20:45     ` Paul E. McKenney

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=alA1a8eMZQ0eli4T@tardis.local \
    --to=boqun@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=paulmck@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome