* [BUG: 6.6.y] bpf fentry hook on _raw_spin_lock_irqsave triggers hard lockup
@ 2026-07-29 7:53 Feng Yang
2026-07-29 8:29 ` Greg KH
0 siblings, 1 reply; 2+ messages in thread
From: Feng Yang @ 2026-07-29 7:53 UTC (permalink / raw)
To: bpf, stable; +Cc: andrii, eddyz87, ast, daniel, memxor, martin.lau, song
When attaching fentry programs to _raw_spin_lock_irqsave/_raw_spin_unlock_irqrestore on
the v6.6 kernel and using the BPF ring buffer within BPF programs, we encounter a hard LOCKUP.
Reproducible BPF code is shown below:
static inline int test(void *ctx)
{
struct event *event;
event = reserve_buf(sizeof(*event));
if (!event)
return 0;
submit_buf(ctx, event, sizeof(*event));
return 0;
}
SEC("fentry/_raw_spin_lock_irqsave")
int BPF_PROG(aa)
{
return test(ctx);
}
SEC("fentry/_raw_spin_unlock_irqrestore")
int BPF_PROG(bb)
{
return test(ctx);
}
We suspect the hard LOCKUP is caused by the call chain:
aa->test->reserve_buf->_raw_spin_lock_irqsave->_raw_spin_unlock_irqrestore->bb->test->reserve_buf->_raw_spin_lock_irqsave.
Mainline has merged the rqspinlock patchset
(https://lore.kernel.org/all/20250411101759.4061366-1-memxor@gmail.com/)
which resolves this issue. Should we backport the fix?
Alternatively, would a fix modeled after this patch
https://lore.kernel.org/bpf/20201029071925.3103400-3-songliubraving@fb.com/
as outlined below be viable?
--- a/kernel/bpf/ringbuf.c
+++ b/kernel/bpf/ringbuf.c
@@ -30,6 +30,7 @@ struct bpf_ringbuf {
struct page **pages;
int nr_pages;
raw_spinlock_t spinlock ____cacheline_aligned_in_smp;
+ int __percpu *ringbuf_lock;
/* 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
@@ -165,6 +166,8 @@ static void bpf_ringbuf_notify(struct irq_work *work)
* considering that the maximum value of data_sz is (4GB - 1), there
* will be no overflow, so just note the size limit in the comments.
*/
+static void bpf_ringbuf_free(struct bpf_ringbuf *rb);
+
static struct bpf_ringbuf *bpf_ringbuf_alloc(size_t data_sz, int numa_node)
{
struct bpf_ringbuf *rb;
@@ -178,6 +181,12 @@ static struct bpf_ringbuf *bpf_ringbuf_alloc(size_t data_sz, int numa_node)
init_waitqueue_head(&rb->waitq);
init_irq_work(&rb->work, bpf_ringbuf_notify);
+ rb->ringbuf_lock = __alloc_percpu_gfp(sizeof(int), sizeof(int), GFP_USER);
+ if (!rb->ringbuf_lock) {
+ bpf_ringbuf_free(rb);
+ return NULL;
+ }
+
rb->mask = data_sz - 1;
rb->consumer_pos = 0;
rb->producer_pos = 0;
@@ -215,6 +224,7 @@ static struct bpf_map *ringbuf_map_alloc(union bpf_attr *attr)
static void bpf_ringbuf_free(struct bpf_ringbuf *rb)
{
+ free_percpu(rb->ringbuf_lock);
irq_work_sync(&rb->work);
/* copy pages pointer and nr_pages to local variable, as we are going
@@ -418,9 +428,19 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
cons_pos = smp_load_acquire(&rb->consumer_pos);
+ preempt_disable();
+ if (unlikely(__this_cpu_inc_return(*rb->ringbuf_lock) != 1)) {
+ __this_cpu_dec(*rb->ringbuf_lock);
+ preempt_enable();
+ return NULL;
+ }
+
if (in_nmi()) {
- if (!raw_spin_trylock_irqsave(&rb->spinlock, flags))
+ if (!raw_spin_trylock_irqsave(&rb->spinlock, flags)) {
+ __this_cpu_dec(*rb->ringbuf_lock);
+ preempt_enable();
return NULL;
+ }
} else {
raw_spin_lock_irqsave(&rb->spinlock, flags);
}
@@ -449,6 +469,8 @@ 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_spin_unlock_irqrestore(&rb->spinlock, flags);
+ __this_cpu_dec(*rb->ringbuf_lock);
+ preempt_enable();
return NULL;
}
@@ -461,6 +483,8 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
smp_store_release(&rb->producer_pos, new_prod_pos);
raw_spin_unlock_irqrestore(&rb->spinlock, flags);
+ __this_cpu_dec(*rb->ringbuf_lock);
+ preempt_enable();
return (void *)hdr + BPF_RINGBUF_HDR_SZ;
}
Thanks,
Feng
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [BUG: 6.6.y] bpf fentry hook on _raw_spin_lock_irqsave triggers hard lockup
2026-07-29 7:53 [BUG: 6.6.y] bpf fentry hook on _raw_spin_lock_irqsave triggers hard lockup Feng Yang
@ 2026-07-29 8:29 ` Greg KH
0 siblings, 0 replies; 2+ messages in thread
From: Greg KH @ 2026-07-29 8:29 UTC (permalink / raw)
To: Feng Yang
Cc: bpf, stable, andrii, eddyz87, ast, daniel, memxor, martin.lau,
song
On Wed, Jul 29, 2026 at 03:53:22PM +0800, Feng Yang wrote:
> When attaching fentry programs to _raw_spin_lock_irqsave/_raw_spin_unlock_irqrestore on
> the v6.6 kernel and using the BPF ring buffer within BPF programs, we encounter a hard LOCKUP.
>
> Reproducible BPF code is shown below:
>
> static inline int test(void *ctx)
> {
> struct event *event;
>
> event = reserve_buf(sizeof(*event));
> if (!event)
> return 0;
>
> submit_buf(ctx, event, sizeof(*event));
>
> return 0;
> }
>
> SEC("fentry/_raw_spin_lock_irqsave")
> int BPF_PROG(aa)
> {
> return test(ctx);
> }
>
> SEC("fentry/_raw_spin_unlock_irqrestore")
> int BPF_PROG(bb)
> {
> return test(ctx);
> }
>
> We suspect the hard LOCKUP is caused by the call chain:
> aa->test->reserve_buf->_raw_spin_lock_irqsave->_raw_spin_unlock_irqrestore->bb->test->reserve_buf->_raw_spin_lock_irqsave.
>
> Mainline has merged the rqspinlock patchset
> (https://lore.kernel.org/all/20250411101759.4061366-1-memxor@gmail.com/)
> which resolves this issue. Should we backport the fix?
>
> Alternatively, would a fix modeled after this patch
> https://lore.kernel.org/bpf/20201029071925.3103400-3-songliubraving@fb.com/
> as outlined below be viable?
Do not do stable-only patches, that's not how the stable trees work.
Fix the issue in Linus's tree first, and then backport the needed
changes to the older trees.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-29 8:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-29 7:53 [BUG: 6.6.y] bpf fentry hook on _raw_spin_lock_irqsave triggers hard lockup Feng Yang
2026-07-29 8:29 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox