From nobody Sat Jul 25 05:22:33 2026 Received: from out-177.mta0.migadu.com (out-177.mta0.migadu.com [91.218.175.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 90199342C98 for ; Fri, 17 Jul 2026 11:42:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288551; cv=none; b=Wn4tJZN/w1XVethvIdJsSTlufDbPTocuFvoNoJH8IMO9QbPvmePUMnDarFLWR7MJ5A1JBtNZJwQSNG6vNRzzZk9Rke3fzF9EnemxolRZh4G5EhKWrcLBQ4uQAP3tig6VCDWwM7B1LgotYNQ5fvfjqRL2GD8W2agn/XNdW0sNg/s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288551; c=relaxed/simple; bh=edW/zkxQxHYY/xoESPYEqRNXd9pMHIOihUL5aFJKh68=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TpL5CfEcSS47lpYwgKfrPc0HN6Bo9w4512EmPFubE9LBRrL//3ZIyvk+O2Al9Wu1OifTT6j4Hml8Py4aT2oa57QY4wd+te7qqsJz940l/YmUFxHdH+2vJZk25S6HLYbnpRQrfAuSrWgGiZi+3Hkp2rq1lTWwyJ5XNEdVZrDAk78= 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=m3aDTVBA; arc=none smtp.client-ip=91.218.175.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="m3aDTVBA" 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=1784288547; 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=RrPtZPFmU7k8SyJGbrsegJWZtSKVS++WfilbkTIJ0YE=; b=m3aDTVBAkDOtk3sYl2jKd2hEMKKFGueSdrbnfQNZnEaBVKI/v0MY0jc1LvzBRU66gWlfXa qu+6MOXR+CvF5InDU9x1mTn37STRAoPrtufeS+y2cWsFl38+knbLQvaOpMHTsRyEsPXDpc ELKySs4QGBiraRzaKHwy2uXM/pURWnc= From: Jiayuan Chen To: bpf@vger.kernel.org Cc: Jiayuan Chen , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Song Liu , Yonghong Song , Jiri Olsa , Emil Tsalapatis , Shuah Khan , Woojin Ji , Puranjay Mohan , Saket Kumar Bhaskar , Ihor Solodrai , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH bpf-next v2 1/4] bpf: Pass arena instead of scratch_page to the pte callbacks Date: Fri, 17 Jul 2026 19:37:01 +0800 Message-ID: <20260717114117.350851-2-jiayuan.chen@linux.dev> In-Reply-To: <20260717114117.350851-1-jiayuan.chen@linux.dev> References: <20260717114117.350851-1-jiayuan.chen@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" Replace the scratch_page field in the pte-callback data with the arena pointer; later patches use other arena fields from these callbacks. No functional change. Signed-off-by: Jiayuan Chen Reviewed-by: Emil Tsalapatis --- kernel/bpf/arena.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c index 80b7b8a69446..8dbc24460890 100644 --- a/kernel/bpf/arena.c +++ b/kernel/bpf/arena.c @@ -143,14 +143,14 @@ static long compute_pgoff(struct bpf_arena *arena, lo= ng uaddr) } =20 struct apply_range_data { + struct bpf_arena *arena; struct page **pages; - struct page *scratch_page; int i; }; =20 struct clear_range_data { + struct bpf_arena *arena; struct llist_head *free_pages; - struct page *scratch_page; }; =20 static int apply_range_set_cb(pte_t *pte, unsigned long addr, void *data) @@ -180,7 +180,7 @@ static int apply_range_set_cb(pte_t *pte, unsigned long= addr, void *data) =20 if (pte_none(old)) continue; - if (WARN_ON_ONCE(pte_page(old) !=3D d->scratch_page)) + if (WARN_ON_ONCE(pte_page(old) !=3D d->arena->scratch_page)) return -EBUSY; ptep_get_and_clear(&init_mm, addr, pte); flush_tlb_before_set(addr); @@ -227,7 +227,7 @@ static int apply_range_clear_cb(pte_t *pte, unsigned lo= ng addr, void *data) * scratches its PTE. A later bpf_arena_free_pages() over that range walks * here. Without the skip, scratch_page would be freed. */ - if (page =3D=3D d->scratch_page) + if (page =3D=3D d->arena->scratch_page) return 0; =20 __llist_add(&page->pcp_llist, d->free_pages); @@ -506,8 +506,7 @@ static vm_fault_t arena_vm_fault(struct vm_fault *vmf) if (ret) goto out_sigsegv_memcg; =20 - struct apply_range_data data =3D { .pages =3D &page, .i =3D 0, - .scratch_page =3D arena->scratch_page }; + struct apply_range_data data =3D { .arena =3D arena, .pages =3D &page, .i= =3D 0 }; /* Account into memcg of the process that created bpf_arena */ ret =3D bpf_map_alloc_pages(map, NUMA_NO_NODE, 1, &page); if (ret) { @@ -696,8 +695,8 @@ static long arena_alloc_pages(struct bpf_arena *arena, = long uaddr, long page_cnt bpf_map_memcg_exit(old_memcg, new_memcg); return 0; } + data.arena =3D arena; data.pages =3D pages; - data.scratch_page =3D arena->scratch_page; =20 if (raw_res_spin_lock_irqsave(&arena->spinlock, flags)) goto out_free_pages; @@ -873,8 +872,8 @@ static void arena_free_pages(struct bpf_arena *arena, l= ong uaddr, long page_cnt, range_tree_set(&arena->rt, pgoff, page_cnt); =20 init_llist_head(&free_pages); + cdata.arena =3D arena; cdata.free_pages =3D &free_pages; - cdata.scratch_page =3D arena->scratch_page; /* clear ptes and collect struct pages */ apply_to_existing_page_range(&init_mm, kaddr, page_cnt << PAGE_SHIFT, apply_range_clear_cb, &cdata); @@ -981,8 +980,8 @@ static void arena_free_worker(struct work_struct *work) bpf_map_memcg_enter(&arena->map, &old_memcg, &new_memcg); =20 init_llist_head(&free_pages); + cdata.arena =3D arena; cdata.free_pages =3D &free_pages; - cdata.scratch_page =3D arena->scratch_page; arena_vm_start =3D bpf_arena_get_kern_vm_start(arena); user_vm_start =3D bpf_arena_get_user_vm_start(arena); =20 --=20 2.43.0 From nobody Sat Jul 25 05:22:33 2026 Received: from out-183.mta0.migadu.com (out-183.mta0.migadu.com [91.218.175.183]) (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 99FF6342C98 for ; Fri, 17 Jul 2026 11:43:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.183 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288601; cv=none; b=Y4JFYOWhUH2dzOyJlhhFbZsVNGBFhGcky6Hqo86qC8+ZEFrtocF9mWQ+hp21JBQJ7ShYjFwah8etHR6Fcqt3J6zK+WFUUHliZwlyjd8JTX5RVprsJRBln/F6MBhs92FErjSx23mKiIObZr5Uq8fD5DJsvzHF3dyjGkHWKW8TUnM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288601; c=relaxed/simple; bh=R/PjILtLGH0Og7Z6ijXBQuX230HRVp0zhLQ4KuBkfpo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Aql5eHl/q5qjMUr/VXlf5ByVJSnt/yA5Vx4eSPnGhytypbSAys85VC892xv80LlKEX1M82k/FW1uZlOrQy2XfxBRyl8CpvmJUBkQd4wCt3Zm3KI4fCaAqIxqY2plqooTTPgYQwIxoNN7WM4mm5OG2hOm+poi8IYPafuzEdHCY7Y= 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=FCBIpIbe; arc=none smtp.client-ip=91.218.175.183 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="FCBIpIbe" 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=1784288596; 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=EG3yfFOxHkF+iZYHcUrq5joNhYwWSGYUc8Ed1Yg5oiw=; b=FCBIpIbef36YErJZJuOhzh740U/sqWq1Yxm6O2i4n8no89kAd/UcrcgsJHokA+cQTcand1 nW8OIYKXNC0lxedyHuPNeBNeaXgDf2JzAp8cQH6Ez19vYFw2jpuiQMYugz8EHo/gVOTp/s q6PiqkUav9/EsOsjTOFVlAWV/Rj2b24= From: Jiayuan Chen To: bpf@vger.kernel.org Cc: Jiayuan Chen , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Song Liu , Yonghong Song , Jiri Olsa , Emil Tsalapatis , Shuah Khan , Woojin Ji , Puranjay Mohan , Saket Kumar Bhaskar , Ihor Solodrai , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH bpf-next v2 2/4] bpf: Add memory usage for arena Date: Fri, 17 Jul 2026 19:37:02 +0800 Message-ID: <20260717114117.350851-3-jiayuan.chen@linux.dev> In-Reply-To: <20260717114117.350851-1-jiayuan.chen@linux.dev> References: <20260717114117.350851-1-jiayuan.chen@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" arena is the only map type whose map_mem_usage() still returns 0, so "bpftool map show" and fdinfo always showed 0 memlock for an arena no matter how many pages it had. Count the pages that are actually mapped into the arena: bump a counter in apply_range_set_cb() when a page goes in and drop it in apply_range_clear_cb() when a page goes out, both under the arena spinlock. map_mem_usage() then just returns nr_pages << PAGE_SHIFT. Only real data pages are counted, not the scratch page. Signed-off-by: Jiayuan Chen Reviewed-by: Emil Tsalapatis --- To sashiko: 1. __bpf_alloc_page::can_alloc_pages already check whether we are under loc= k. 2. apply_to_page_range() does not allocate page tables here. arena_map_allo= c() already did it. --- kernel/bpf/arena.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c index 8dbc24460890..f046e878f7ae 100644 --- a/kernel/bpf/arena.c +++ b/kernel/bpf/arena.c @@ -55,8 +55,10 @@ struct bpf_arena { struct vm_struct *kern_vm; struct page *scratch_page; struct range_tree rt; - /* protects rt */ + /* protects rt and nr_pages */ rqspinlock_t spinlock; + /* number of pages currently populated in the arena */ + u64 nr_pages; struct list_head vma_list; /* protects vma_list */ struct mutex lock; @@ -196,6 +198,7 @@ static int apply_range_set_cb(pte_t *pte, unsigned long= addr, void *data) set_pte_at(&init_mm, addr, pte, pteval); #endif d->i++; + WRITE_ONCE(d->arena->nr_pages, d->arena->nr_pages + 1); return 0; } =20 @@ -231,6 +234,7 @@ static int apply_range_clear_cb(pte_t *pte, unsigned lo= ng addr, void *data) return 0; =20 __llist_add(&page->pcp_llist, d->free_pages); + WRITE_ONCE(d->arena->nr_pages, d->arena->nr_pages - 1); return 0; } =20 @@ -413,7 +417,9 @@ static int arena_map_check_btf(struct bpf_map *map, con= st struct btf *btf, =20 static u64 arena_map_mem_usage(const struct bpf_map *map) { - return 0; + struct bpf_arena *arena =3D container_of(map, struct bpf_arena, map); + + return (u64)READ_ONCE(arena->nr_pages) << PAGE_SHIFT; } =20 struct vma_list { --=20 2.43.0 From nobody Sat Jul 25 05:22:33 2026 Received: from out-173.mta0.migadu.com (out-173.mta0.migadu.com [91.218.175.173]) (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 9BBD73EC6B3 for ; Fri, 17 Jul 2026 11:44:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288650; cv=none; b=bHUJiJU3m48++tRodkcgk3SrxwLCk/FCHFtvemNvydQVH33oSBOKwnFX0laFEQ/zqAxaAz2X2cyz0eEaKQKzUJDGofRncxl4DZVEaKCgVvaRofyrqthMB7I8iNH5KtXLw8oSA6XFZngGHPM6M+iXaNDM6a0dfiMaCVUPHnqr7DU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288650; c=relaxed/simple; bh=dWmvp43IKVubgTW2JezViPLkZPLDROd8zoUS3bFSBiY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WSETLrEevkauEcodSxCF4mw6gZkOUnR0jKxftE06iYeCmwg+MWoMtgZ2XjaZaZ3K2OQ2EkWN8avnxxHCiXDaUcFh7W8uNjQb864zsu9focfwbSmCCy/9RZ0xXzJuJo1uAWPyl0dWR6Ds3R2fi8pOa7034VOmz+4E+OVTjVa1cdU= 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=uO7+lBxO; arc=none smtp.client-ip=91.218.175.173 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="uO7+lBxO" 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=1784288644; 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=KqllfF2sjMjOj+hOcfuOpL2ZB+wrDIwyDEsvI0vRnLw=; b=uO7+lBxO6UkP+MNeT3ZzvAzKKDc3IkSKT0v/DiBu2a91C39NDWAfp6FBSW83VR4GMQCt/N 2dkaPde4KGpzjQQN60kfNP3wF2/V6MD0mXBTFaMUAULT304jPdDFj4X9r/KaSZ9ZBzDjyu edyvSLvgMMAo8rqleLb3Ws1dHNeuAGY= From: Jiayuan Chen To: bpf@vger.kernel.org Cc: Jiayuan Chen , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Song Liu , Yonghong Song , Jiri Olsa , Emil Tsalapatis , Shuah Khan , Woojin Ji , Puranjay Mohan , Saket Kumar Bhaskar , Ihor Solodrai , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH bpf-next v2 3/4] selftests/bpf: Run arena tests serially Date: Fri, 17 Jul 2026 19:37:03 +0800 Message-ID: <20260717114117.350851-4-jiayuan.chen@linux.dev> In-Reply-To: <20260717114117.350851-1-jiayuan.chen@linux.dev> References: <20260717114117.350851-1-jiayuan.chen@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" Every arena reserves a 4GB kernel vmalloc region at creation, and on a KASAN build that eagerly populates ~512MB of shadow memory per arena. When several arena tests run in parallel their shadow adds up, exhausts the memory of a small CI VM and trips the OOM killer during map creation. Make the dedicated arena tests (arena_* and libarena*) serial so they no longer pile up in the parallel phase. That alone brings the peak number of live arenas back within the CI memory budget. A few other tests such as verifier_arena*, stream and compute_live_registers create an arena too, but they run inside shared RUN_TESTS()/RUN() suites, so turning them serial would drag many unrelated subtests along with them. Leave those as-is. Signed-off-by: Jiayuan Chen Reviewed-by: Emil Tsalapatis --- tools/testing/selftests/bpf/prog_tests/arena_atomics.c | 2 +- tools/testing/selftests/bpf/prog_tests/arena_direct_value.c | 2 +- tools/testing/selftests/bpf/prog_tests/arena_htab.c | 2 +- tools/testing/selftests/bpf/prog_tests/arena_list.c | 2 +- tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c | 2 +- tools/testing/selftests/bpf/prog_tests/arena_strsearch.c | 2 +- tools/testing/selftests/bpf/prog_tests/libarena.c | 2 +- tools/testing/selftests/bpf/prog_tests/libarena_asan.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/arena_atomics.c b/tools= /testing/selftests/bpf/prog_tests/arena_atomics.c index d98577a6babc..1ad5d03d07ad 100644 --- a/tools/testing/selftests/bpf/prog_tests/arena_atomics.c +++ b/tools/testing/selftests/bpf/prog_tests/arena_atomics.c @@ -222,7 +222,7 @@ static void test_store_release(struct arena_atomics *sk= el) "store_release64_result"); } =20 -void test_arena_atomics(void) +void serial_test_arena_atomics(void) { struct arena_atomics *skel; int err; diff --git a/tools/testing/selftests/bpf/prog_tests/arena_direct_value.c b/= tools/testing/selftests/bpf/prog_tests/arena_direct_value.c index 4b4adb3f4b71..01fcf4965ea4 100644 --- a/tools/testing/selftests/bpf/prog_tests/arena_direct_value.c +++ b/tools/testing/selftests/bpf/prog_tests/arena_direct_value.c @@ -66,7 +66,7 @@ static void test_arena_direct_value_one_past_end(void) close(map_fd); } =20 -void test_arena_direct_value(void) +void serial_test_arena_direct_value(void) { if (test__start_subtest("one_past_end")) test_arena_direct_value_one_past_end(); diff --git a/tools/testing/selftests/bpf/prog_tests/arena_htab.c b/tools/te= sting/selftests/bpf/prog_tests/arena_htab.c index d69fd2465f53..91ccf0402980 100644 --- a/tools/testing/selftests/bpf/prog_tests/arena_htab.c +++ b/tools/testing/selftests/bpf/prog_tests/arena_htab.c @@ -81,7 +81,7 @@ static void test_arena_htab_asm(void) arena_htab_asm__destroy(skel); } =20 -void test_arena_htab(void) +void serial_test_arena_htab(void) { if (test__start_subtest("arena_htab_llvm")) test_arena_htab_llvm(); diff --git a/tools/testing/selftests/bpf/prog_tests/arena_list.c b/tools/te= sting/selftests/bpf/prog_tests/arena_list.c index 4f2866a615ce..2648e06f53d0 100644 --- a/tools/testing/selftests/bpf/prog_tests/arena_list.c +++ b/tools/testing/selftests/bpf/prog_tests/arena_list.c @@ -68,7 +68,7 @@ static void test_arena_list_add_del(int cnt, bool nonslee= pable) arena_list__destroy(skel); } =20 -void test_arena_list(void) +void serial_test_arena_list(void) { if (test__start_subtest("arena_list_1")) test_arena_list_add_del(1, false); diff --git a/tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c b/too= ls/testing/selftests/bpf/prog_tests/arena_spin_lock.c index acb9d53b5973..545b05d7a0aa 100644 --- a/tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c +++ b/tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c @@ -101,7 +101,7 @@ static void test_arena_spin_lock_size(int size) return; } =20 -void test_arena_spin_lock(void) +void serial_test_arena_spin_lock(void) { repeat =3D 1000; if (test__start_subtest("arena_spin_lock_1")) diff --git a/tools/testing/selftests/bpf/prog_tests/arena_strsearch.c b/too= ls/testing/selftests/bpf/prog_tests/arena_strsearch.c index f81a0c066505..0c1c6cbfa0f1 100644 --- a/tools/testing/selftests/bpf/prog_tests/arena_strsearch.c +++ b/tools/testing/selftests/bpf/prog_tests/arena_strsearch.c @@ -23,7 +23,7 @@ static void test_arena_str(void) arena_strsearch__destroy(skel); } =20 -void test_arena_strsearch(void) +void serial_test_arena_strsearch(void) { if (test__start_subtest("arena_strsearch")) test_arena_str(); diff --git a/tools/testing/selftests/bpf/prog_tests/libarena.c b/tools/test= ing/selftests/bpf/prog_tests/libarena.c index ba5a5a50f7c0..df7e4b8dc394 100644 --- a/tools/testing/selftests/bpf/prog_tests/libarena.c +++ b/tools/testing/selftests/bpf/prog_tests/libarena.c @@ -202,7 +202,7 @@ static void run_libarena_parallel_test(struct libarena = *skel, struct bpf_program run_libarena_parallel_fini(skel, name, prefixlen); } =20 -void test_libarena(void) +void serial_test_libarena(void) { struct arena_alloc_reserve_args args; struct libarena *skel; diff --git a/tools/testing/selftests/bpf/prog_tests/libarena_asan.c b/tools= /testing/selftests/bpf/prog_tests/libarena_asan.c index f897405f701d..9c31b17dbf39 100644 --- a/tools/testing/selftests/bpf/prog_tests/libarena_asan.c +++ b/tools/testing/selftests/bpf/prog_tests/libarena_asan.c @@ -85,7 +85,7 @@ static void run_test(void) * Run the test depending on whether LLVM can compile arena ASAN * programs. */ -void test_libarena_asan(void) +void serial_test_libarena_asan(void) { #ifdef HAS_BPF_ARENA_ASAN run_test(); --=20 2.43.0 From nobody Sat Jul 25 05:22:33 2026 Received: from out-183.mta0.migadu.com (out-183.mta0.migadu.com [91.218.175.183]) (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 93D973E44F3 for ; Fri, 17 Jul 2026 11:44:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.183 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288696; cv=none; b=LaAZ0DTkYsiUekYr84Ny21UT6cqMrNto2yuGHfJMg2Wp2zaYSN3id67fnZQeIj5RLl7z9XAcnkSDDmAjFxCTbJFg9o0Z15anXksHkM8G7kOmSkk6zb2T+QrbfRpDSYBw2G7opuhJq6mDCRGKw3NHjoDT+k/t1aIO3XnqgWoPtYQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288696; c=relaxed/simple; bh=rZ6jtUtSS4GNvi72UDkBya22b0zrLtMt0p6uqNOse0w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qes5FXsJUOOAmNSxH3ohodSTS4+IM0fn8IHDRuH8XD+ffCp09qn9VM2ATUAPVXZatHXVhGjFWmQT74vXldhC+QXGu2/2vW6RRYUX6y+puVkssULGx3udcQSyQSqq2EhH0ODi1q9i682OZsL2HLyUZphaDL//YDvQtWihZoIsVLc= 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=ZxOMH26m; arc=none smtp.client-ip=91.218.175.183 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="ZxOMH26m" 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=1784288692; 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=1pxOHl5VNgUMJYzm9Si1cE6oOE/fofw0uz5fZqdv2jQ=; b=ZxOMH26mSPS/itcdlO5CylgPBi1DV7rO+w/ufiNVFgSaB80TLaKazwPU7WulCRzUSeZubw HQw+unsA/CK6mnSdQ7IvH2GtkLoFAx6OeDEhgEJGGVt2wSXrfrTg/nGI5uAOmDsYHS9oAW g3CPwb3iGr6TSyhBNYdC9RhIlYAi2WQ= From: Jiayuan Chen To: bpf@vger.kernel.org Cc: Jiayuan Chen , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Song Liu , Yonghong Song , Jiri Olsa , Emil Tsalapatis , Shuah Khan , Woojin Ji , Puranjay Mohan , Saket Kumar Bhaskar , Ihor Solodrai , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH bpf-next v2 4/4] selftests/bpf: Add tests for memory usage for arena Date: Fri, 17 Jul 2026 19:37:04 +0800 Message-ID: <20260717114117.350851-5-jiayuan.chen@linux.dev> In-Reply-To: <20260717114117.350851-1-jiayuan.chen@linux.dev> References: <20260717114117.350851-1-jiayuan.chen@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" Allocate and free arena pages, both from BPF and via user-space fault-in, and check that the map's memlock in fdinfo tracks the number of pages that are actually populated. Like the other arena tests it runs serially. test: ./test_progs -a arena_mem_usage #5 arena_mem_usage:OK Summary: 1/0 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Jiayuan Chen Reviewed-by: Emil Tsalapatis --- .../bpf/prog_tests/arena_mem_usage.c | 122 ++++++++++++++++++ .../selftests/bpf/progs/arena_mem_usage.c | 40 ++++++ 2 files changed, 162 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/arena_mem_usage.c create mode 100644 tools/testing/selftests/bpf/progs/arena_mem_usage.c diff --git a/tools/testing/selftests/bpf/prog_tests/arena_mem_usage.c b/too= ls/testing/selftests/bpf/prog_tests/arena_mem_usage.c new file mode 100644 index 000000000000..14c2d1a1d673 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/arena_mem_usage.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#ifndef PAGE_SIZE /* on some archs it comes in sys/user.h */ +#include +#define PAGE_SIZE getpagesize() +#endif + +#include "arena_mem_usage.skel.h" + +/* + * arena_map_mem_usage() is surfaced to user space through the map's + * /proc//fdinfo/ "memlock:" line (the same value bpftool map show + * prints). Read it directly so the test has no external dependency. + */ +static long map_memlock(int map_fd) +{ + char path[64], line[128]; + long memlock =3D -1; + FILE *f; + + snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", map_fd); + f =3D fopen(path, "r"); + if (!ASSERT_OK_PTR(f, "open_fdinfo")) + return -1; + while (fgets(line, sizeof(line), f)) { + if (sscanf(line, "memlock:\t%ld", &memlock) =3D=3D 1) + break; + } + fclose(f); + ASSERT_NEQ(memlock, -1, "parse_memlock"); + return memlock; +} + +static int run(struct bpf_program *prog, const char *name) +{ + LIBBPF_OPTS(bpf_test_run_opts, opts); + int err =3D bpf_prog_test_run_opts(bpf_program__fd(prog), &opts); + + if (!ASSERT_OK(err, name)) + return -1; + if (!ASSERT_OK(opts.retval, name)) + return -1; + return 0; +} + +void serial_test_arena_mem_usage(void) +{ + struct arena_mem_usage *skel; + const long ps =3D PAGE_SIZE; + char *base; + size_t sz; + int fd, i; + + skel =3D arena_mem_usage__open_and_load(); + if (!ASSERT_OK_PTR(skel, "open_load")) + return; + fd =3D bpf_map__fd(skel->maps.arena); + + /* Fresh arena: no data pages, and the scratch page is not counted. */ + ASSERT_EQ(map_memlock(fd), 0, "initial"); + + /* BPF-side allocation of 17 pages. */ + skel->bss->alloc_cnt =3D 17; + if (run(skel->progs.alloc, "alloc")) + goto out; + /* + * A NULL ptr means bpf_arena_alloc_pages() itself failed (e.g. the host + * is under memory pressure), not a miscount -- flag it distinctly so a + * red CI run is not mistaken for a counting bug. + */ + if (!ASSERT_OK_PTR(skel->bss->ptr, "arena_alloc_pages")) + goto out; + ASSERT_EQ(map_memlock(fd), 17 * ps, "after_alloc"); + + /* Free a single page (arena_free_pages page_cnt=3D=3D1 path). */ + skel->bss->free_byte_off =3D 0; + skel->bss->free_cnt =3D 1; + if (run(skel->progs.free_pages, "free_one")) + goto out; + ASSERT_EQ(map_memlock(fd), 16 * ps, "after_free_one"); + + /* Free ten pages in one call (bulk path); only the freed pages count. */ + skel->bss->free_byte_off =3D 1 * ps; + skel->bss->free_cnt =3D 10; + if (run(skel->progs.free_pages, "free_bulk")) + goto out; + ASSERT_EQ(map_memlock(fd), 6 * ps, "after_free_bulk"); + + /* Free the remaining six -> arena empty again. */ + skel->bss->free_byte_off =3D 11 * ps; + skel->bss->free_cnt =3D 6; + if (run(skel->progs.free_pages, "free_rest")) + goto out; + ASSERT_EQ(map_memlock(fd), 0, "after_free_rest"); + + /* + * User-space fault-in: touching unallocated arena pages allocates them + * through arena_vm_fault(). libbpf mmap()s the arena at map_extra during + * load, so bpf_map__initial_value() hands back that base. + */ + base =3D bpf_map__initial_value(skel->maps.arena, &sz); + if (!ASSERT_OK_PTR(base, "arena_base")) + goto out; + for (i =3D 0; i < 8; i++) + base[i * ps] =3D 1; + ASSERT_EQ(map_memlock(fd), 8 * ps, "after_faultin"); + + /* + * Free the faulted-in pages from BPF. They are mapped into the user vma + * (elevated refcount), so this also exercises the zap path. + */ + skel->bss->ptr =3D base; + skel->bss->free_byte_off =3D 0; + skel->bss->free_cnt =3D 8; + if (run(skel->progs.free_pages, "free_faulted")) + goto out; + ASSERT_EQ(map_memlock(fd), 0, "after_free_faulted"); +out: + arena_mem_usage__destroy(skel); +} diff --git a/tools/testing/selftests/bpf/progs/arena_mem_usage.c b/tools/te= sting/selftests/bpf/progs/arena_mem_usage.c new file mode 100644 index 000000000000..455ecd669a5a --- /dev/null +++ b/tools/testing/selftests/bpf/progs/arena_mem_usage.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include "bpf_arena_common.h" + +struct { + __uint(type, BPF_MAP_TYPE_ARENA); + __uint(map_flags, BPF_F_MMAPABLE); + __uint(max_entries, 1000); /* number of pages */ +#ifdef __TARGET_ARCH_arm64 + __ulong(map_extra, 0x1ull << 32); /* start of mmap() region */ +#else + __ulong(map_extra, 0x1ull << 44); /* start of mmap() region */ +#endif +} arena SEC(".maps"); + +void __arena *ptr; +int alloc_cnt; /* in: pages to allocate */ +long free_byte_off; /* in: byte offset within ptr to start freeing */ +int free_cnt; /* in: pages to free */ + +SEC("syscall") +int alloc(void *ctx) +{ + ptr =3D bpf_arena_alloc_pages(&arena, NULL, alloc_cnt, NUMA_NO_NODE, 0); + /* Success/failure is checked from user space via skel->bss->ptr. */ + return 0; +} + +SEC("syscall") +int free_pages(void *ctx) +{ + if (!ptr) + return 1; + bpf_arena_free_pages(&arena, (char __arena *)ptr + free_byte_off, free_cn= t); + return 0; +} + +char _license[] SEC("license") =3D "GPL"; --=20 2.43.0