Thread (38 messages) 38 messages, 4 authors, 2026-01-13

Re: [PATCH bpf-next v3 01/16] bpf: Convert bpf_selem_unlink_map to failable

From: Martin KaFai Lau <martin.lau@linux.dev>
Date: 2026-01-08 20:40:41
Also in: bpf

On 12/18/25 10:27 AM, bot+bpf-ci@kernel.org wrote:
quoted
diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c
index e2fe6c32822b..4e3f227fd634 100644
--- a/kernel/bpf/bpf_local_storage.c
+++ b/kernel/bpf/bpf_local_storage.c
[ ... ]
quoted
@@ -488,9 +516,10 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap,
  {
  	struct bpf_local_storage_data *old_sdata = NULL;
  	struct bpf_local_storage_elem *alloc_selem, *selem = NULL;
+	struct bpf_local_storage_map_bucket *b, *old_b = NULL;
+	unsigned long flags, b_flags, old_b_flags;
  	struct bpf_local_storage *local_storage;
  	HLIST_HEAD(old_selem_free_list);
-	unsigned long flags;
  	int err;
[ ... ]
quoted
@@ -574,20 +603,37 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap,
  		goto unlock;
  	}

+	b = select_bucket(smap, selem);
+
+	if (old_sdata) {
+		old_b = select_bucket(smap, SELEM(old_sdata));
+		old_b = old_b == b ? NULL : old_b;
+	}
+
+	raw_spin_lock_irqsave(&b->lock, b_flags);
+
+	if (old_b)
+		raw_spin_lock_irqsave(&old_b->lock, old_b_flags);
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Could this introduce an ABBA deadlock between two bucket locks? If two
threads concurrently update storage on the same map with different owners,
their new and old selems could hash to different buckets with reversed
order:

   Thread 1: new_selem -> bucket_A, old_selem -> bucket_B
             acquires b->lock (A), then waits for old_b->lock (B)

   Thread 2: new_selem -> bucket_B, old_selem -> bucket_A
             acquires b->lock (B), then waits for old_b->lock (A)

Since the locks are regular raw_spinlocks (not rqspinlocks yet), they
will block indefinitely in this scenario.

Note: I see that commit 615477732ee8 ("bpf: Change local_storage->lock
and b->lock to rqspinlock") later in this series changes to rqspinlock
which has deadlock detection and can return -EDEADLK instead of blocking.
However, in the current commit the locks are still raw_spinlocks.
I just catch up on this ai-review, so I made a similar comment on this 
raw_spinlock in another reply instead of here. imo, we should still 
avoid this even the rqspinlock is used in the later patch.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help