From nobody Sun May 24 20:33:27 2026 Received: from out-170.mta1.migadu.com (out-170.mta1.migadu.com [95.215.58.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4E3334A79D for ; Thu, 21 May 2026 22:50:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779403861; cv=none; b=O5RDGL5aA/HM44SMYMiyOl3ImRlnl/gX/tDlS/zoVc5ULPyldEP3tGTJ+a9dHHGdaTPAyEeg2Bx1shwIPqz5lFmKAo9U26whdR/qTCSVNh02GzbxMLPFfnoUwawbdVKRQbz4/jOf/SdxjmsPhVyCgwPbpmbv44FXKDscUcOMkAk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779403861; c=relaxed/simple; bh=2l1/L1N2BsBa6UDCrcEyhM5/RBwZisw1PiRzwSFdwtA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hdm2Wh00ThpRwRvp3bEOkoI7uuPw5xfH7Tv57vPF7TZp4HIGufJGKRDk4tMfL6lV42wj/5lTOZs2R8Bl3tvLitmQKkrzma0h0t9n+AWitY6VkjNFstlq33bH2SRjPrDQSqNYVfDrJp8I2WPuiyk9GseDaYWx3BPToj2WO4lO4QE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Kb6oHEl4; arc=none smtp.client-ip=95.215.58.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Kb6oHEl4" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1779403858; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=39Oy0nfDjc6LjnlHZaW6NwycZGuFEV9tuMsdrt9m9AE=; b=Kb6oHEl4EyP+rYiJHJCZcVbUiYEOeww79bMjcBj+1pV2UgQ+Sjs9PEdOAqVJsDbumGJBq3 Bu8B+eATxYoVC9x7QNGnqJRaOvbpf5cGRcgBHhAEMb+EI9G4C3Z9s/6xPQtplUP2dD9ij6 4TkYCPWM9r2OIZC6CaS6GgKpj38lKFY= From: Ihor Solodrai To: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Eduard Zingerman , Kumar Kartikeya Dwivedi Cc: Puranjay Mohan , Shakeel Butt , Mykyta Yatsenko , bpf@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@meta.com Subject: [PATCH bpf-next v6 1/3] bpf: Factor out stack_map build ID helpers Date: Thu, 21 May 2026 15:50:20 -0700 Message-ID: <20260521225022.2695755-2-ihor.solodrai@linux.dev> In-Reply-To: <20260521225022.2695755-1-ihor.solodrai@linux.dev> References: <20260521225022.2695755-1-ihor.solodrai@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Factor out helpers from stack_map_get_build_id_offset() in preparation for adding a sleepable build ID resolution path. No functional changes. Acked-by: Mykyta Yatsenko Signed-off-by: Ihor Solodrai --- kernel/bpf/stackmap.c | 51 ++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c index da3d328f5c15..4c753e02c415 100644 --- a/kernel/bpf/stackmap.c +++ b/kernel/bpf/stackmap.c @@ -152,6 +152,28 @@ static int fetch_build_id(struct vm_area_struct *vma, = unsigned char *build_id, b : build_id_parse_nofault(vma, build_id, NULL); } =20 +static inline void stack_map_build_id_set_ip(struct bpf_stack_build_id *id) +{ + id->status =3D BPF_STACK_BUILD_ID_IP; + memset(id->build_id, 0, BUILD_ID_SIZE_MAX); +} + +static inline u64 stack_map_build_id_offset(unsigned long vm_pgoff, + unsigned long vm_start, u64 ip) +{ + return (vm_pgoff << PAGE_SHIFT) + ip - vm_start; +} + +static inline void stack_map_build_id_set_valid(struct bpf_stack_build_id = *id, + u64 offset, + const unsigned char *build_id) +{ + id->status =3D BPF_STACK_BUILD_ID_VALID; + id->offset =3D offset; + if (id->build_id !=3D build_id) + memcpy(id->build_id, build_id, BUILD_ID_SIZE_MAX); +} + /* * Expects all id_offs[i].ip values to be set to correct initial IPs. * They will be subsequently: @@ -165,44 +187,43 @@ static int fetch_build_id(struct vm_area_struct *vma,= unsigned char *build_id, b static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_of= fs, u32 trace_nr, bool user, bool may_fault) { - int i; struct mmap_unlock_irq_work *work =3D NULL; bool irq_work_busy =3D bpf_mmap_unlock_get_irq_work(&work); + bool has_user_ctx =3D user && current && current->mm; struct vm_area_struct *vma, *prev_vma =3D NULL; - const char *prev_build_id; + const unsigned char *prev_build_id; + int i; =20 /* If the irq_work is in use, fall back to report ips. Same * fallback is used for kernel stack (!user) on a stackmap with * build_id. */ - if (!user || !current || !current->mm || irq_work_busy || - !mmap_read_trylock(current->mm)) { + if (!has_user_ctx || irq_work_busy || !mmap_read_trylock(current->mm)) { /* cannot access current->mm, fall back to ips */ - for (i =3D 0; i < trace_nr; i++) { - id_offs[i].status =3D BPF_STACK_BUILD_ID_IP; - memset(id_offs[i].build_id, 0, BUILD_ID_SIZE_MAX); - } + for (i =3D 0; i < trace_nr; i++) + stack_map_build_id_set_ip(&id_offs[i]); return; } =20 for (i =3D 0; i < trace_nr; i++) { u64 ip =3D READ_ONCE(id_offs[i].ip); + u64 offset; =20 if (range_in_vma(prev_vma, ip, ip)) { vma =3D prev_vma; - memcpy(id_offs[i].build_id, prev_build_id, BUILD_ID_SIZE_MAX); - goto build_id_valid; + offset =3D stack_map_build_id_offset(vma->vm_pgoff, vma->vm_start, ip); + stack_map_build_id_set_valid(&id_offs[i], offset, prev_build_id); + prev_build_id =3D id_offs[i].build_id; + continue; } vma =3D find_vma(current->mm, ip); if (!vma || fetch_build_id(vma, id_offs[i].build_id, may_fault)) { /* per entry fall back to ips */ - id_offs[i].status =3D BPF_STACK_BUILD_ID_IP; - memset(id_offs[i].build_id, 0, BUILD_ID_SIZE_MAX); + stack_map_build_id_set_ip(&id_offs[i]); continue; } -build_id_valid: - id_offs[i].offset =3D (vma->vm_pgoff << PAGE_SHIFT) + ip - vma->vm_start; - id_offs[i].status =3D BPF_STACK_BUILD_ID_VALID; + offset =3D stack_map_build_id_offset(vma->vm_pgoff, vma->vm_start, ip); + stack_map_build_id_set_valid(&id_offs[i], offset, id_offs[i].build_id); prev_vma =3D vma; prev_build_id =3D id_offs[i].build_id; } --=20 2.54.0 From nobody Sun May 24 20:33:27 2026 Received: from out-171.mta1.migadu.com (out-171.mta1.migadu.com [95.215.58.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF476352037 for ; Thu, 21 May 2026 22:51:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779403867; cv=none; b=GKco97rlXaEutCYU1+feWkFod8MP1aSiWt1X/DzG6GsRD/eh0RPUj6l8fKY7aSXHVCRpSs/7Uo3ClkDvNeLRAh9k4gT2g3f2bsnqdK3Gc6lWJ8/OqF56JvrcH/OhoYIn+fzJN4OCVX2/j1yEeM3YwLMUuVaphDHPO+S9KLWmkn0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779403867; c=relaxed/simple; bh=pXP2lgITJSNU5AU+E2Fxyy7VNAs4tMt0EponXJD3sCI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mzNuGAc/UCmP+DTJnP8ILHXX0x9spLnX0fZn5fo/K2d6pbUpZ7+JkEdTk4WhSfljiyTAnIbIJdC9q0k0YSC64/7prT8DtehBOlshmQMRNHxvhaaW1jli12LLn4kjqJVzgDEUkD7jpRB+Yvrov9W3MLx2701Qc3Wj2aWmS4KZk8o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=jNajj+fa; arc=none smtp.client-ip=95.215.58.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="jNajj+fa" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1779403861; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tuLRrdRs2RHud2IJwYpExSlcTjkkwwdVwHfuP0dVWHc=; b=jNajj+favgBFDR/t6VaAwKgOQj6722pjFDsC6INDK3Qpp2yVm6lFvDwJaYc79hC4LkirqF bWIN7B8TCYhwtw1A8J/b6Fmbu3npryDS1mePMTcGYNf7zxeKA71sYgOjoFLP3ANT2EFSyi Gylj/CZ+rbMSC8zDr8hnAoR592we4pY= From: Ihor Solodrai To: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Eduard Zingerman , Kumar Kartikeya Dwivedi Cc: Puranjay Mohan , Shakeel Butt , Mykyta Yatsenko , bpf@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@meta.com Subject: [PATCH bpf-next v6 2/3] bpf: Avoid faultable build ID reads under mm locks Date: Thu, 21 May 2026 15:50:21 -0700 Message-ID: <20260521225022.2695755-3-ihor.solodrai@linux.dev> In-Reply-To: <20260521225022.2695755-1-ihor.solodrai@linux.dev> References: <20260521225022.2695755-1-ihor.solodrai@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Sleepable build ID parsing can block in __kernel_read() [1], so the stackmap sleepable path must not call it while holding mmap_lock or a per-VMA read lock. The issue and the fix are conceptually similar to a recent procfs patch [2]. Resolve each covered VMA with a stable read-side reference, preferring lock_vma_under_rcu() and falling back to mmap_read_trylock() only long enough to acquire the VMA read lock. Take a reference to the backing file, drop the VMA lock, and then parse the build ID through (sleepable) build_id_parse_file(). We have to use mmap_read_trylock() (and give up on failure) in this context because taking mmap_read_lock() is generally unsafe on code paths reachable from BPF programs [3], and may lead to deadlocks. [1] https://lore.kernel.org/all/20251218005818.614819-1-shakeel.butt@linux.= dev/ [2] https://lore.kernel.org/all/20260128183232.2854138-1-andrii@kernel.org/ [3] https://lore.kernel.org/bpf/2895ecd8-df1e-4cc0-b9f9-aef893dc2360@linux.= dev/ Fixes: d4dd9775ec24 ("bpf: wire up sleepable bpf_get_stack() and bpf_get_ta= sk_stack() helpers") Suggested-by: Puranjay Mohan Signed-off-by: Ihor Solodrai --- kernel/bpf/stackmap.c | 107 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c index 4c753e02c415..95336c0e8b56 100644 --- a/kernel/bpf/stackmap.c +++ b/kernel/bpf/stackmap.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "percpu_freelist.h" #include "mmap_unlock_work.h" =20 @@ -174,6 +175,107 @@ static inline void stack_map_build_id_set_valid(struc= t bpf_stack_build_id *id, memcpy(id->build_id, build_id, BUILD_ID_SIZE_MAX); } =20 +struct stack_map_vma_lock { + bool vma_locked; + struct vm_area_struct *vma; + struct mm_struct *mm; +}; + +static struct vm_area_struct *stack_map_lock_vma(struct stack_map_vma_lock= *lock, unsigned long ip) +{ + struct mm_struct *mm =3D lock->mm; + struct vm_area_struct *vma; + + if (WARN_ON_ONCE(!mm)) + return NULL; + + vma =3D lock_vma_under_rcu(mm, ip); + if (vma) + goto vma_locked; + + /* + * Taking mmap_read_lock() is unsafe here, because the caller + * BPF program might already hold it, causing a deadlock. + */ + if (!mmap_read_trylock(mm)) + return NULL; + + vma =3D vma_lookup(mm, ip); + if (!vma) { + mmap_read_unlock(mm); + return NULL; + } + +#ifdef CONFIG_PER_VMA_LOCK + if (!vma_start_read_locked(vma)) { + mmap_read_unlock(mm); + return NULL; + } + mmap_read_unlock(mm); +#else + mmap_read_unlock(mm); + return NULL; +#endif +vma_locked: + lock->vma_locked =3D true; + lock->vma =3D vma; + return vma; +} + +static void stack_map_unlock_vma(struct stack_map_vma_lock *lock) +{ + struct vm_area_struct *vma =3D lock->vma; + + if (lock->vma_locked) { + if (WARN_ON_ONCE(!vma)) + goto out; + vma_end_read(vma); + } +out: + lock->vma_locked =3D false; + lock->vma =3D NULL; +} + +static void stack_map_get_build_id_offset_sleepable(struct bpf_stack_build= _id *id_offs, + u32 trace_nr) +{ + struct mm_struct *mm =3D current->mm; + struct stack_map_vma_lock lock =3D { + .vma_locked =3D false, + .vma =3D NULL, + .mm =3D mm, + }; + struct vm_area_struct *vma; + struct file *file; + u64 offset; + u64 ip; + + for (u32 i =3D 0; i < trace_nr; i++) { + ip =3D READ_ONCE(id_offs[i].ip); + + vma =3D stack_map_lock_vma(&lock, ip); + if (!vma || !vma->vm_file) { + stack_map_build_id_set_ip(&id_offs[i]); + stack_map_unlock_vma(&lock); + continue; + } + + file =3D get_file(vma->vm_file); + offset =3D stack_map_build_id_offset(vma->vm_pgoff, vma->vm_start, ip); + stack_map_unlock_vma(&lock); + + /* build_id_parse_file() may block on filesystem reads */ + if (build_id_parse_file(file, id_offs[i].build_id, NULL)) { + stack_map_build_id_set_ip(&id_offs[i]); + fput(file); + continue; + } + fput(file); + + stack_map_build_id_set_valid(&id_offs[i], offset, id_offs[i].build_id); + } +} + /* * Expects all id_offs[i].ip values to be set to correct initial IPs. * They will be subsequently: @@ -194,6 +296,11 @@ static void stack_map_get_build_id_offset(struct bpf_s= tack_build_id *id_offs, const unsigned char *prev_build_id; int i; =20 + if (may_fault && has_user_ctx) { + stack_map_get_build_id_offset_sleepable(id_offs, trace_nr); + return; + } + /* If the irq_work is in use, fall back to report ips. Same * fallback is used for kernel stack (!user) on a stackmap with * build_id. --=20 2.54.0 From nobody Sun May 24 20:33:27 2026 Received: from out-177.mta1.migadu.com (out-177.mta1.migadu.com [95.215.58.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 70BD3286881 for ; Thu, 21 May 2026 22:51:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779403869; cv=none; b=KydY+rG1d1wvf4FKUu/yd2W8xs08tcwNWygQnBXraZ9H7t7D6htjv9gIcKLzEMMdwIx+9BkQZvP/DB/ETiINFF/Gdp1ZmkOxdReGTAf1OoazANr4Degq+iMGI0kKpYOdvnkcjnwHu+/RIHBr+T1rwUQbuj3SOAulPU+ktrr5AZc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779403869; c=relaxed/simple; bh=59CB+nPUZqTvo1tK5kyFcmQcM2kFAHkCc9lFZiEnUkU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kMSeqxnDMr3MyDRS2CplQCCuBw8lARrMuUEZUBTaVmzW0LkJUjtu7Yb9da+Rg3hPzsbYN+QfWnSvxFxX88kP4DHDgSzinr7ODCQ8sWH9gJIlTzlugO6Raq5niKXKlbkFV1WkFY5wkQpmXu4/mK4y2UHaVU06lfCJnYghRz7UkAo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=pmknv/Q1; arc=none smtp.client-ip=95.215.58.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="pmknv/Q1" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1779403865; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=soCrvY+G9j9s8Up9MbZp+KmpDH/Fu49zSezrypYZ7SE=; b=pmknv/Q18ouHvs2TlAH2cWY5ZhoxfG35Su+eS36kwjbnMPdLLgeqV7CMWTmaaH37dZLhrE tmhVLkFCt6yLM5KRluzGC8ZgUjdiFivd6nqEexg5UYs+CY8sJzAbVFHCxAHtoO3qw3ga3p eBUwx/0FH7j3z3u9j6lhP5Imb8SRNvU= From: Ihor Solodrai To: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Eduard Zingerman , Kumar Kartikeya Dwivedi Cc: Puranjay Mohan , Shakeel Butt , Mykyta Yatsenko , bpf@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@meta.com Subject: [PATCH bpf-next v6 3/3] bpf: Cache build IDs in sleepable stackmap path Date: Thu, 21 May 2026 15:50:22 -0700 Message-ID: <20260521225022.2695755-4-ihor.solodrai@linux.dev> In-Reply-To: <20260521225022.2695755-1-ihor.solodrai@linux.dev> References: <20260521225022.2695755-1-ihor.solodrai@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Stack traces often contain adjacent IPs from the same VMA or from different VMAs backed by the same ELF file. Cache the last successfully parsed build id together with the resolved VMA range and backing file so the sleepable build id path can avoid repeated VMA locking and file parsing in common cases. Suggested-by: Mykyta Yatsenko Acked-by: Mykyta Yatsenko Signed-off-by: Ihor Solodrai Acked-by: Andrii Nakryiko --- kernel/bpf/stackmap.c | 52 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c index 95336c0e8b56..0d641ac39227 100644 --- a/kernel/bpf/stackmap.c +++ b/kernel/bpf/stackmap.c @@ -245,6 +245,14 @@ static void stack_map_get_build_id_offset_sleepable(st= ruct bpf_stack_build_id *i .vma =3D NULL, .mm =3D mm, }; + struct { + struct file *file; + const unsigned char *build_id; + unsigned long vm_start; + unsigned long vm_end; + unsigned long vm_pgoff; + } cache =3D {}; + unsigned long vm_pgoff, vm_start, vm_end; struct vm_area_struct *vma; struct file *file; u64 offset; @@ -253,6 +261,17 @@ static void stack_map_get_build_id_offset_sleepable(st= ruct bpf_stack_build_id *i for (u32 i =3D 0; i < trace_nr; i++) { ip =3D READ_ONCE(id_offs[i].ip); =20 + /* + * Range cache fast path: if ip falls within the previously + * resolved VMA range, reuse the cache build_id without + * re-acquiring the VMA lock. + */ + if (cache.build_id && ip >=3D cache.vm_start && ip < cache.vm_end) { + offset =3D stack_map_build_id_offset(cache.vm_pgoff, cache.vm_start, ip= ); + stack_map_build_id_set_valid(&id_offs[i], offset, cache.build_id); + continue; + } + vma =3D stack_map_lock_vma(&lock, ip); if (!vma || !vma->vm_file) { stack_map_build_id_set_ip(&id_offs[i]); @@ -260,8 +279,26 @@ static void stack_map_get_build_id_offset_sleepable(st= ruct bpf_stack_build_id *i continue; } =20 - file =3D get_file(vma->vm_file); - offset =3D stack_map_build_id_offset(vma->vm_pgoff, vma->vm_start, ip); + file =3D vma->vm_file; + vm_pgoff =3D vma->vm_pgoff; + vm_start =3D vma->vm_start; + vm_end =3D vma->vm_end; + offset =3D stack_map_build_id_offset(vm_pgoff, vm_start, ip); + + if (file =3D=3D cache.file) { + /* + * Same backing file as previous (e.g. different VMAs + * of the same ELF binary). Reuse the cache build_id. + */ + stack_map_unlock_vma(&lock); + stack_map_build_id_set_valid(&id_offs[i], offset, cache.build_id); + cache.vm_start =3D vm_start; + cache.vm_end =3D vm_end; + cache.vm_pgoff =3D vm_pgoff; + continue; + } + + file =3D get_file(file); stack_map_unlock_vma(&lock); =20 /* build_id_parse_file() may block on filesystem reads */ @@ -270,10 +307,19 @@ static void stack_map_get_build_id_offset_sleepable(s= truct bpf_stack_build_id *i fput(file); continue; } - fput(file); =20 stack_map_build_id_set_valid(&id_offs[i], offset, id_offs[i].build_id); + if (cache.file) + fput(cache.file); + cache.file =3D file; + cache.build_id =3D id_offs[i].build_id; + cache.vm_start =3D vm_start; + cache.vm_end =3D vm_end; + cache.vm_pgoff =3D vm_pgoff; } + + if (cache.file) + fput(cache.file); } =20 /* --=20 2.54.0