From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-m12737.qiye.163.com (mail-m12737.qiye.163.com [115.236.127.37]) (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 901334E4C2B; Fri, 9 Oct 2026 13:45:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.236.127.37 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791553560; cv=none; b=JUnER39F0XyOR+vZzdR0SUwBpInW3vzgWiYAZrbtzFs/ze7yOaVFRAa4HEeKmNZosw2KfuNhKUO7HjXxSwR3cnxT/p1gt1hbcJV9VyndgKcE4P/8oWvLyVVh52EOBOsQPA9phuSDc7c4fFQYBXLA2A6vsKXuyKAx7kcFtoHZ818= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791553560; c=relaxed/simple; bh=ejix/GHT5Iy+bkG+fkhiG/LYt+lDYDbsduLb+mrvkek=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=sj/04SFlUJYyp2SfuXth2ULMwLsQfKjgWPesBQv01HQ5eDuNCDJTZjtKjGgTI9A/x36Ye5/NvIy+NaxYS1jIwJFCYfxNFSZ2V4+aD72ulBgkUwLW34W4zCnzWXakESBB56EytKdxpn73N6k3aFU87LuKQKf8lyCE85zEruEUFt4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=easystack.cn; spf=pass smtp.mailfrom=easystack.cn; arc=none smtp.client-ip=115.236.127.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=easystack.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=easystack.cn Received: from localhost.localdomain (unknown [218.94.118.90]) by smtp.qiye.163.com (Hmail) with ESMTP id 1fe2901a1; Fri, 9 Oct 2026 19:23:28 +0800 (GMT+08:00) From: Zhen Ni To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, eddyz87@gmail.com, memxor@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, jolsa@kernel.org, emil@etsalapatis.com, ihor.solodrai@linux.dev, akpm@linux-foundation.org, vbabka@kernel.org, surenb@google.com, mhocko@suse.com, brendan.jackman@linux.dev, hannes@cmpxchg.org, ziy@nvidia.com, shuah@kernel.org Cc: bpf@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Zhen Ni Subject: [PATCH 3/6] mm/page_owner: add open-coded page_owner iterator Date: Fri, 9 Oct 2026 19:23:05 +0800 Message-Id: <20261009112308.240769-4-zhen.ni@easystack.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20261009112308.240769-1-zhen.ni@easystack.cn> References: <20261009112308.240769-1-zhen.ni@easystack.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-HM-Tid: 0aa12067610e0229kunmd33b3e054cb283 X-HM-MType: 1 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFJQjdXWRgWCB1ZQUpXWS1ZQUlXWQ8JGhUIEh9ZQVkaSBhNVh4aSEtKHUIZTUtLHVYVFA kWGhdVGRETFhoSFyQUDg9ZV1kYEgtZQVlJSkNVQk9VSkpDVUJLWVdZFhoPEhUdFFlBWU9LSFVKS0 lPT09IVUpLS1VKQktLWQY+ Add an open-coded bpf_iter over the pages eligible for page_owner output, reusing page_owner_next_eligible(). A sleepable BPF program drives it with bpf_iter_page_owner_new()/next()/destroy(); each next() returns the page_owner_scan. po_snap is copied inside the page_ext RCU window, so the program needs no RCU section when it reads it. Also add bpf_page_owner_stack_snprint(), which renders the stack trace for a stack_depot handle into a caller-provided buffer. Signed-off-by: Zhen Ni --- kernel/bpf/helpers.c | 6 +++++ mm/page_owner_iter.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 712dca5a2c5b..23a2d2d71f4d 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -4946,6 +4946,12 @@ BTF_ID_FLAGS(func, bpf_iter_dmabuf_new, KF_ITER_NEW | KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_iter_dmabuf_next, KF_ITER_NEXT | KF_RET_NULL | KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_iter_dmabuf_destroy, KF_ITER_DESTROY | KF_SLEEPABLE) #endif +#ifdef CONFIG_PAGE_OWNER +BTF_ID_FLAGS(func, bpf_iter_page_owner_new, KF_ITER_NEW | KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_iter_page_owner_next, KF_ITER_NEXT | KF_RET_NULL | KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_iter_page_owner_destroy, KF_ITER_DESTROY | KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_page_owner_stack_snprint, KF_SLEEPABLE) +#endif BTF_ID_FLAGS(func, __bpf_trap) BTF_ID_FLAGS(func, bpf_strcmp, KF_PERFMON); BTF_ID_FLAGS(func, bpf_strcasecmp, KF_PERFMON); diff --git a/mm/page_owner_iter.c b/mm/page_owner_iter.c index 33dc9dcd59de..80693d417407 100644 --- a/mm/page_owner_iter.c +++ b/mm/page_owner_iter.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "page_owner.h" @@ -114,3 +115,54 @@ int page_owner_iter_register(void) return bpf_iter_reg_target(&page_owner_iter_reg_info); } + +/* opaque to BPF programs */ +struct bpf_iter_page_owner { + __u64 __opaque[16]; +} __attribute__((aligned(8))); + +struct bpf_iter_page_owner_kern { + struct page_owner_scan scan; +} __attribute__((aligned(8))); + +__bpf_kfunc_start_defs(); + +__bpf_kfunc int bpf_iter_page_owner_new(struct bpf_iter_page_owner *it) +{ + struct bpf_iter_page_owner_kern *kit = (void *)it; + + BUILD_BUG_ON(sizeof(*kit) > sizeof(*it)); + BUILD_BUG_ON(__alignof__(*kit) != __alignof__(*it)); + + kit->scan.pfn = min_low_pfn; + kit->scan.page = NULL; + return 0; +} + +__bpf_kfunc struct page_owner_scan * +bpf_iter_page_owner_next(struct bpf_iter_page_owner *it) +{ + struct bpf_iter_page_owner_kern *kit = (void *)it; + + cond_resched(); + + if (kit->scan.page) + kit->scan.pfn++; + + if (!page_owner_next_eligible(&kit->scan)) + return NULL; + + return &kit->scan; +} + +__bpf_kfunc void bpf_iter_page_owner_destroy(struct bpf_iter_page_owner *it) +{ +} + +__bpf_kfunc int bpf_page_owner_stack_snprint(depot_stack_handle_t handle, + char *buf, u32 buf_size) +{ + return stack_depot_snprint(handle, buf, buf_size, 0); +} + +__bpf_kfunc_end_defs(); -- 2.20.1