On Thu, Aug 21, 2025 at 9:26 AM Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> wrote: > > We noticed potential lock ups and delays in progs running in NMI context > with the rqspinlock changes, which suggests more improvements need to be > made before we can support ring buffer updates in such a context safely. > Revert the change for now. > > Reported-by: Josef Bacik <josef@xxxxxxxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > Fixes: a650d38915c1 ("bpf: Convert ringbuf map to rqspinlock") > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> > --- > kernel/bpf/ringbuf.c | 17 ++++++++++------- > 1 file changed, 10 insertions(+), 7 deletions(-) > patch bot seems to be ignoring this patch, it was applied to bpf tree, thanks! > diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c > index 719d73299397..1499d8caa9a3 100644 > --- a/kernel/bpf/ringbuf.c > +++ b/kernel/bpf/ringbuf.c > @@ -11,7 +11,6 @@ > #include <linux/kmemleak.h> > #include <uapi/linux/btf.h> > #include <linux/btf_ids.h> > -#include <asm/rqspinlock.h> > > #define RINGBUF_CREATE_FLAG_MASK (BPF_F_NUMA_NODE) > > @@ -30,7 +29,7 @@ struct bpf_ringbuf { > u64 mask; > struct page **pages; > int nr_pages; > - rqspinlock_t spinlock ____cacheline_aligned_in_smp; > + raw_spinlock_t spinlock ____cacheline_aligned_in_smp; > /* For user-space producer ring buffers, an atomic_t busy bit is used > * to synchronize access to the ring buffers in the kernel, rather than > * the spinlock that is used for kernel-producer ring buffers. This is > @@ -174,7 +173,7 @@ static struct bpf_ringbuf *bpf_ringbuf_alloc(size_t data_sz, int numa_node) > if (!rb) > return NULL; > > - raw_res_spin_lock_init(&rb->spinlock); > + raw_spin_lock_init(&rb->spinlock); > atomic_set(&rb->busy, 0); > init_waitqueue_head(&rb->waitq); > init_irq_work(&rb->work, bpf_ringbuf_notify); > @@ -417,8 +416,12 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size) > > cons_pos = smp_load_acquire(&rb->consumer_pos); > > - if (raw_res_spin_lock_irqsave(&rb->spinlock, flags)) > - return NULL; > + if (in_nmi()) { > + if (!raw_spin_trylock_irqsave(&rb->spinlock, flags)) > + return NULL; > + } else { > + raw_spin_lock_irqsave(&rb->spinlock, flags); > + } > > pend_pos = rb->pending_pos; > prod_pos = rb->producer_pos; > @@ -443,7 +446,7 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size) > */ > if (new_prod_pos - cons_pos > rb->mask || > new_prod_pos - pend_pos > rb->mask) { > - raw_res_spin_unlock_irqrestore(&rb->spinlock, flags); > + raw_spin_unlock_irqrestore(&rb->spinlock, flags); > return NULL; > } > > @@ -455,7 +458,7 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size) > /* pairs with consumer's smp_load_acquire() */ > smp_store_release(&rb->producer_pos, new_prod_pos); > > - raw_res_spin_unlock_irqrestore(&rb->spinlock, flags); > + raw_spin_unlock_irqrestore(&rb->spinlock, flags); > > return (void *)hdr + BPF_RINGBUF_HDR_SZ; > } > -- > 2.50.0 >