All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf] bpf: Don't hold pack_mutex over arm64 IPIs
@ 2026-10-24  3:10 Alexei Starovoitov
  2026-10-27 19:59 ` Puranjay Mohan
  0 siblings, 1 reply; 3+ messages in thread
From: Alexei Starovoitov @ 2026-10-24  3:10 UTC (permalink / raw)
  To: bpf; +Cc: daniel, andrii, eddyz87, memxor

From: Alexei Starovoitov <ast@kernel.org>

bpf_prog_pack_free() calls bpf_arch_text_invalidate() with pack_mutex
held. On arm64 it interrupts all other CPUs and waits for them:

  bpf_prog_free_deferred
    bpf_jit_free
      bpf_prog_pack_free
        bpf_arch_text_invalidate
          aarch64_insn_set
            flush_icache_range
              kick_all_cpus_sync

When many progs are freed at once, every prog load waits in
bpf_prog_pack_alloc() for all of these broadcasts. On arm64 hosts with
many CPUs we saw hung task reports with sk_attach_filter() blocked on
pack_mutex for minutes.

The bits of the range are still set in the bitmap during the
invalidation, so nobody can allocate it and the pack cannot be freed.
Drop pack_mutex around bpf_arch_text_invalidate() and take it again to
clear the bits.

Do it on arm64 only. x86, riscv, powerpc and loongarch take text_mutex in
bpf_arch_text_invalidate(). The frees would wait there instead, and the
load would wait for them in bpf_arch_text_copy().

Tested in arm64 KVM guests with 16 and 96 cpus on a 96 cpu host. cpus/2
processes attach a cBPF filter to 256 sockets and close them in a loop
for 20 sec. One more process attaches a filter every msec. Median of
5 runs.

The loops get more done. Sockets attached and closed in 20 sec, in
millions (higher is better):

             before  after
  16 cpus       1.6    4.7
  96 cpus      0.38    4.2

setsockopt(SO_ATTACH_FILTER) of the process that attaches every msec
takes less time, in msec (lower is better):

                16 cpus          96 cpus
             before  after    before  after
  avg          0.97   0.18        11   0.54
  p99            20    2.8       421    4.0
  max           204     90      1738    255

Fixes: 1dad391daef1 ("bpf, arm64: use bpf_prog_pack for memory management")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
 kernel/bpf/core.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 3030beb531d9..0fef87cfa152 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1069,8 +1069,17 @@ void bpf_prog_pack_free(void *ptr, u32 size)
 	nbits = BPF_PROG_SIZE_TO_NBITS(size);
 	pos = ((unsigned long)ptr - (unsigned long)pack->ptr) >> BPF_PROG_CHUNK_SHIFT;
 
+	/*
+	 * arm64 sends IPI to all CPUs in bpf_arch_text_invalidate().
+	 * Don't hold pack_mutex across it. The bits are still set,
+	 * so the range cannot be reused and the pack cannot be freed.
+	 */
+	if (IS_ENABLED(CONFIG_ARM64))
+		mutex_unlock(&pack_mutex);
 	WARN_ONCE(bpf_arch_text_invalidate(ptr, size),
 		  "bpf_prog_pack bug: missing bpf_arch_text_invalidate?\n");
+	if (IS_ENABLED(CONFIG_ARM64))
+		mutex_lock(&pack_mutex);
 
 	bitmap_clear(pack->bitmap, pos, nbits);
 

base-commit: b116ac6087541d3d98031e786adbe9c733cd6df3
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-28  4:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-24  3:10 [PATCH bpf] bpf: Don't hold pack_mutex over arm64 IPIs Alexei Starovoitov
2026-10-27 19:59 ` Puranjay Mohan
2026-10-28  4:23   ` Alexei Starovoitov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.