All of lore.kernel.org
 help / color / mirror / Atom feed
From: Emil Tsalapatis <emil@etsalapatis.com>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, andrii@kernel.org, eddyz87@gmail.com,
	memxor@gmail.com, daniel@iogearbox.net,
	Emil Tsalapatis <emil@etsalapatis.com>
Subject: [PATCH bpf-next v4 2/8] bpf: Associate arena pages with their mapping
Date: Wed, 14 Oct 2026 23:34:36 +0000	[thread overview]
Message-ID: <20261014233442.8392-3-emil@etsalapatis.com> (raw)
In-Reply-To: <20261014233442.8392-1-emil@etsalapatis.com>

Associate arena backing pages with the arena's private mapping and set
their page offsets. This allows the fault handler to delegate user PTE
installation to generic MM code, which is itself useful for avoiding
races with kfunc-related arena operations.

Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
---
 kernel/bpf/arena.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c
index b95ffdb14417..650baa09fcb5 100644
--- a/kernel/bpf/arena.c
+++ b/kernel/bpf/arena.c
@@ -202,6 +202,9 @@ static int apply_range_set_cb(pte_t *pte, unsigned long addr, void *data)
 		return -EBUSY;
 	set_pte_at(&init_mm, addr, pte, pteval);
 #endif
+	page_folio(page)->index = compute_pgoff(d->arena,
+						addr - bpf_arena_get_kern_vm_start(d->arena));
+	page->mapping = d->arena->file->f_mapping;
 	WARN_ON_ONCE(llist_del_first(d->pages) != node);
 	d->i++;
 	WRITE_ONCE(d->arena->nr_pages, d->arena->nr_pages + 1);
@@ -272,6 +275,17 @@ static int populate_pgtable_except_pte(struct bpf_arena *arena)
 /* The backing file must not hold a map reference. */
 static const struct file_operations arena_backing_fops = {};
 
+/* Arena pages are not page-cache entries and must not be evicted by MM. */
+static bool arena_release_folio(struct folio *folio, gfp_t gfp)
+{
+	return false;
+}
+
+static const struct address_space_operations arena_aops = {
+	.dirty_folio = noop_dirty_folio,
+	.release_folio = arena_release_folio,
+};
+
 static struct bpf_map *arena_map_alloc(union bpf_attr *attr)
 {
 	struct vm_struct *kern_vm;
@@ -341,6 +355,8 @@ static struct bpf_map *arena_map_alloc(union bpf_attr *attr)
 		err = PTR_ERR(arena->file);
 		goto err_destroy_rt;
 	}
+	arena->file->f_mapping->a_ops = &arena_aops;
+	mapping_set_release_always(arena->file->f_mapping);
 
 	return &arena->map;
 
@@ -355,6 +371,14 @@ static struct bpf_map *arena_map_alloc(union bpf_attr *attr)
 	return ERR_PTR(err);
 }
 
+static void arena_put_page(struct page *page)
+{
+	lock_page(page);
+	page->mapping = NULL;
+	unlock_page(page);
+	__free_page(page);
+}
+
 static int existing_page_cb(pte_t *ptep, unsigned long addr, void *data)
 {
 	struct bpf_arena *arena = data;
@@ -378,7 +402,7 @@ static int existing_page_cb(pte_t *ptep, unsigned long addr, void *data)
 	 * the TLB entries can stick around and continue to permit access to
 	 * the freed page. So it all relies on 1.
 	 */
-	__free_page(page);
+	arena_put_page(page);
 	return 0;
 }
 
@@ -939,7 +963,7 @@ static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt,
 			 * page_cnt is big it's faster to do the batched zap.
 			 */
 			zap_pages(arena, full_uaddr, 1);
-		__free_page(page);
+		arena_put_page(page);
 	}
 	bpf_map_memcg_exit(old_memcg, new_memcg);
 
@@ -1061,7 +1085,7 @@ static void arena_free_worker(struct work_struct *work)
 	/* free all pages collected by apply_to_existing_page_range() in the first loop */
 	llist_for_each_safe(pos, t, __llist_del_all(&free_pages)) {
 		page = llist_entry(pos, struct page, pcp_llist);
-		__free_page(page);
+		arena_put_page(page);
 	}
 
 	bpf_map_memcg_exit(old_memcg, new_memcg);
-- 
2.52.0


  parent reply	other threads:[~2026-10-14 23:34 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-14 23:34 [PATCH bpf-next v4 0/8] bpf: Fix arena memory incoherence Emil Tsalapatis
2026-10-14 23:34 ` [PATCH bpf-next v4 1/8] bpf: Use mapping tree to zap arena VMAs Emil Tsalapatis
2026-10-15  0:33   ` bot+bpf-ci
2026-10-14 23:34 ` Emil Tsalapatis [this message]
2026-10-15  0:01   ` [PATCH bpf-next v4 2/8] bpf: Associate arena pages with their mapping sashiko-bot
2026-10-14 23:34 ` [PATCH bpf-next v4 3/8] bpf: arena: Stop deferred frees before map teardown Emil Tsalapatis
2026-10-14 23:34 ` [PATCH bpf-next v4 4/8] bpf: Update is_range_tree_set to work for consecutive ranges Emil Tsalapatis
2026-10-14 23:34 ` [PATCH bpf-next v4 5/8] bpf: Track availability information for ranges in range tree Emil Tsalapatis
2026-10-14 23:34 ` [PATCH bpf-next v4 6/8] bpf: Fix arena race between page free and alloc leading to incoherency Emil Tsalapatis
2026-10-14 23:34 ` [PATCH bpf-next v4 7/8] bpf: Synchronize arena page faults with page freeing Emil Tsalapatis
2026-10-15  0:33   ` bot+bpf-ci
2026-10-14 23:34 ` [PATCH bpf-next v4 8/8] selftests/bpf: Add arena allocation race tests Emil Tsalapatis
2026-10-14 23:52   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261014233442.8392-3-emil@etsalapatis.com \
    --to=emil@etsalapatis.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=memxor@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.