On 2/13/25 04:35, Alexei Starovoitov wrote: > From: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> > > In !PREEMPT_RT local_lock_irqsave() disables interrupts to protect > critical section, but it doesn't prevent NMI, so the fully reentrant > code cannot use local_lock_irqsave() for exclusive access. > > Introduce localtry_lock_t and localtry_lock_irqsave() that > disables interrupts and sets acquired=1, so localtry_lock_irqsave() > from NMI attempting to acquire the same lock will return false. > > In PREEMPT_RT local_lock_irqsave() maps to preemptible spin_lock(). > Map localtry_lock_irqsave() to preemptible spin_trylock(). > When in hard IRQ or NMI return false right away, since > spin_trylock() is not safe due to PI issues. > > Note there is no need to use local_inc for acquired variable, > since it's a percpu variable with strict nesting scopes. > > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> > Signed-off-by: Alexei Starovoitov <ast@xxxxxxxxxx> ... > > +/* localtry_lock_t variants */ > + > +#define __localtry_lock_init(lock) \ > +do { \ > + __local_lock_init(&(lock)->llock); \ > + WRITE_ONCE(&(lock)->acquired, 0); \ This needs to be WRITE_ONCE((lock)->acquired, 0); I'm adopting this implementation for my next slab sheaves RFC. But I'll want localtry_trylock() without _irqsave too, so I've added it locally. Posting below with the init fix and making the PREEMPT_RT comment clear. Feel free to fold everything, it would make it easier for me. Or just the fixes, if you don't want code you don't use yourself. ----8<----