From nobody Sat Jul 25 20:46:40 2026 Received: from out-182.mta0.migadu.com (out-182.mta0.migadu.com [91.218.175.182]) (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 DAD42370D7C for ; Tue, 14 Jul 2026 01:51:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993900; cv=none; b=Nk+6iuJA2TH2BCD6YvsPUY4fcGAv/23ahS8pk0h6omTT5T3X6L3meFgZ0Pj9iPeFOcSpznRcTiBkoBcNt1sWji0nal38Nvj2CkDAl7X1CR4EqKklWCsl7S7xtYCT5luIqZlfBR1miSf56PgNp+mCvil3ie7CSz3T55V8d8X51Xw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993900; c=relaxed/simple; bh=7fMY4VX6XLd71SFB5aRjSa/17g6ZkUsiC6Yy21LjxOc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bqbqUfvrCiIw71ddWAzuHACWvlUyQOz5xnixd89uVDaHybvQpIAJUgNgYKPyl5z9AY70eYBIdD0ELJ7GkoY8G/s7/5zVXk3aFjmOBYehkENsogKDbdB141mpXXpZlhehrpFvidWlbKNgIS/sV/HCk/8llrvZ8uKWCvaMWB+UvhA= 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=q9MMIWnr; arc=none smtp.client-ip=91.218.175.182 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="q9MMIWnr" 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=1783993896; 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=JMExFnjyQtVXN7x+iPdJHV2C/UohwacNGTdpQ/luPkA=; b=q9MMIWnrG6MMXSjSwOz6WBgZTgDuv8pCguuTBtgut4YzhTSYjwchyKhMO5rI55P04ujT7t cnTinz3UAN7NBNIz8Hbo79jT+K5J6wOXNNHj4gFV/FO/aCezggwftfpIJV4QI+MrmGcU2B myHIU6NqkpZAl2gj8TZx5KCYkxWyUAM= From: Ye Liu To: Andrew Morton , Vlastimil Babka Cc: Ye Liu , Zi Yan , Suren Baghdasaryan , Michal Hocko , Brendan Jackman , Johannes Weiner , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 1/9] mm/page_owner: extract skip_buddy_pages() helper to unify buddy page skipping Date: Tue, 14 Jul 2026 09:51:00 +0800 Message-ID: <20260714015117.78351-2-ye.liu@linux.dev> In-Reply-To: <20260714015117.78351-1-ye.liu@linux.dev> References: <20260714015117.78351-1-ye.liu@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" Three places in page_owner.c duplicate the same pattern: check if a page is PageBuddy, read its order via buddy_order_unsafe(), advance the pfn past the buddy block if the order is valid, and continue. Consolidate them into a single inline helper skip_buddy_pages(). The function returns true (skip) for any buddy page and advances @pfn past the block when the order is valid; returns false if the page is not a buddy page and should be processed normally. The old init_pages_in_zone() variant used "order > 0" as an extra guard before advancing pfn, but the continue was unconditional and (1UL << 0) - 1 =3D=3D 0, so the behaviour is identical. The comment about zone->lock is preserved in the helper's kernel-doc. No functional change. Signed-off-by: Ye Liu Reviewed-by: Zi Yan Reviewed-by: Vlastimil Babka (SUSE) --- mm/page_owner.c | 52 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index 2dddcb6510aa..342549891a8d 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -422,6 +422,29 @@ void __folio_copy_owner(struct folio *newfolio, struct= folio *old) rcu_read_unlock(); } =20 +/* + * Check if a page is a buddy page and advance @pfn past the entire buddy = block. + * This safely reads the buddy order without the zone lock, which may caus= e us + * to skip less than the full buddy block, but that is acceptable for page= owner + * iteration purposes. + * + * Return: true if the page was skipped (caller should continue its loop), + * false if the page is not a buddy page and should be processed n= ormally. + */ +static inline bool skip_buddy_pages(unsigned long *pfn, struct page *page) +{ + unsigned long order; + + if (!PageBuddy(page)) + return false; + + order =3D buddy_order_unsafe(page); + if (order <=3D MAX_PAGE_ORDER) + *pfn +=3D (1UL << order) - 1; + + return true; +} + void pagetypeinfo_showmixedcount_print(struct seq_file *m, pg_data_t *pgdat, struct zone *zone) { @@ -461,14 +484,8 @@ void pagetypeinfo_showmixedcount_print(struct seq_file= *m, if (page_zone(page) !=3D zone) continue; =20 - if (PageBuddy(page)) { - unsigned long freepage_order; - - freepage_order =3D buddy_order_unsafe(page); - if (freepage_order <=3D MAX_PAGE_ORDER) - pfn +=3D (1UL << freepage_order) - 1; + if (skip_buddy_pages(&pfn, page)) continue; - } =20 if (PageReserved(page)) continue; @@ -697,13 +714,8 @@ read_page_owner(struct file *file, char __user *buf, s= ize_t count, loff_t *ppos) } =20 page =3D pfn_to_page(pfn); - if (PageBuddy(page)) { - unsigned long freepage_order =3D buddy_order_unsafe(page); - - if (freepage_order <=3D MAX_PAGE_ORDER) - pfn +=3D (1UL << freepage_order) - 1; + if (skip_buddy_pages(&pfn, page)) continue; - } =20 page_ext =3D page_ext_get(page); if (unlikely(!page_ext)) @@ -798,20 +810,8 @@ static void init_pages_in_zone(struct zone *zone) if (page_zone(page) !=3D zone) continue; =20 - /* - * To avoid having to grab zone->lock, be a little - * careful when reading buddy page order. The only - * danger is that we skip too much and potentially miss - * some early allocated pages, which is better than - * heavy lock contention. - */ - if (PageBuddy(page)) { - unsigned long order =3D buddy_order_unsafe(page); - - if (order > 0 && order <=3D MAX_PAGE_ORDER) - pfn +=3D (1UL << order) - 1; + if (skip_buddy_pages(&pfn, page)) continue; - } =20 if (PageReserved(page)) continue; --=20 2.43.0 From nobody Sat Jul 25 20:46:40 2026 Received: from out-188.mta0.migadu.com (out-188.mta0.migadu.com [91.218.175.188]) (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 F2FAE370D7C for ; Tue, 14 Jul 2026 01:51:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993909; cv=none; b=b+a/eOvrRge2WDASG4i1cA48WReUq759B5AklD8VH61ucsd1SmP4MnY6+sC1IJ/qWk6pOEIwVDfjOENHiqN1SKqlNRwaZEvsVMGKl7A8GYHafo3BRAH5g3aFF1R+0orBWIH/JH8XbzUR26MKcrICJzY6RWFpKZfkXLfwjn3HVxc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993909; c=relaxed/simple; bh=Y4YpGMARZG9c6LwBaYM7iJMqslDF6brT9TtTvVI+1T0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hQcJMV6i9BRAaFoq32pkQqEM8MKALLopU9E+pNzOCdCj6WFWYSpYvWoMFsYXNb8Vlj5K8C3S5LuUBzmoArpByv6tMrKnllzfDaS0q/uwIulKWeHroryoSplz22UrwBClLLcOS0ew/ZsWWQaAr8WtuRXssA31jw1iKWOflONIPFI= 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=evR+b9Hf; arc=none smtp.client-ip=91.218.175.188 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="evR+b9Hf" 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=1783993904; 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=9Uz52W8u4KLE/aWGQJH75bXXpHks/NCvUx2zWmpBg4g=; b=evR+b9HfhPd9/q4bYfexK5ghaI2i9yq2n8g+yuiWZiuKIvA9uQNlLjKbH6uaSpfOTOsidQ reywB8MMasH+G9WTATxb9sIRILQArxH/RHNCAf0nQqYeazABPk/D9GsbUguMPjTSk5Q5TV dUO659U+gWnuDhwAsO1DbvHGThKaW3s= From: Ye Liu To: Andrew Morton , David Hildenbrand , Steven Rostedt , Masami Hiramatsu , Vlastimil Babka , Jan Kiszka , Kieran Bingham Cc: Ye Liu , Zi Yan , Matthew Brost , Joshua Hahn , Rakie Kim , Byungchul Park , Gregory Price , Ying Huang , Alistair Popple , Mathieu Desnoyers , Suren Baghdasaryan , Michal Hocko , Brendan Jackman , Johannes Weiner , linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Subject: [PATCH v6 2/9] mm/page_owner: add MR_NEVER to enum migrate_reason and use it for last_migrate_reason Date: Tue, 14 Jul 2026 09:51:01 +0800 Message-ID: <20260714015117.78351-3-ye.liu@linux.dev> In-Reply-To: <20260714015117.78351-1-ye.liu@linux.dev> References: <20260714015117.78351-1-ye.liu@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" The last_migrate_reason field uses -1 as a sentinel value to mean "no migration has happened". Replace the four bare -1 occurrences by adding a proper MR_NEVER member to enum migrate_reason, defining a corresponding "never_migrated" string in the MIGRATE_REASON trace macro, and updating the GDB page_owner script to use MR_NEVER instead of the hardcoded -1 so that lx-dump-page-owner does not incorrectly report unmigrated pages as migrated. No functional change. Signed-off-by: Ye Liu Reviewed-by: Zi Yan Reviewed-by: Vlastimil Babka (SUSE) --- include/linux/migrate_mode.h | 1 + include/trace/events/migrate.h | 3 ++- mm/page_owner.c | 8 ++++---- scripts/gdb/linux/page_owner.py | 4 +++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/linux/migrate_mode.h b/include/linux/migrate_mode.h index 265c4328b36a..05102d4d2490 100644 --- a/include/linux/migrate_mode.h +++ b/include/linux/migrate_mode.h @@ -25,6 +25,7 @@ enum migrate_reason { MR_LONGTERM_PIN, MR_DEMOTION, MR_DAMON, + MR_NEVER, /* page has never been migrated */ MR_TYPES }; =20 diff --git a/include/trace/events/migrate.h b/include/trace/events/migrate.h index cd01dd7b3640..11bc0aa14c7e 100644 --- a/include/trace/events/migrate.h +++ b/include/trace/events/migrate.h @@ -23,7 +23,8 @@ EM( MR_CONTIG_RANGE, "contig_range") \ EM( MR_LONGTERM_PIN, "longterm_pin") \ EM( MR_DEMOTION, "demotion") \ - EMe(MR_DAMON, "damon") + EM( MR_DAMON, "damon") \ + EMe(MR_NEVER, "never_migrated") =20 /* * First define the enums in the above macros to be exported to userspace diff --git a/mm/page_owner.c b/mm/page_owner.c index 342549891a8d..c2f43ab860eb 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -339,7 +339,7 @@ noinline void __set_page_owner(struct page *page, unsig= ned short order, depot_stack_handle_t handle; =20 handle =3D save_stack(gfp_mask); - __update_page_owner_handle(page, handle, order, gfp_mask, -1, + __update_page_owner_handle(page, handle, order, gfp_mask, MR_NEVER, ts_nsec, current->pid, current->tgid, current->comm); inc_stack_record_count(handle, gfp_mask, 1 << order); @@ -596,7 +596,7 @@ print_page_owner(char __user *buf, size_t count, unsign= ed long pfn, if (ret >=3D count) goto err; =20 - if (page_owner->last_migrate_reason !=3D -1) { + if (page_owner->last_migrate_reason !=3D MR_NEVER) { ret +=3D scnprintf(kbuf + ret, count - ret, "Page has been migrated, last migrate reason: %s\n", migrate_reason_names[page_owner->last_migrate_reason]); @@ -667,7 +667,7 @@ void __dump_page_owner(const struct page *page) stack_depot_print(handle); } =20 - if (page_owner->last_migrate_reason !=3D -1) + if (page_owner->last_migrate_reason !=3D MR_NEVER) pr_alert("page has been migrated, last migrate reason: %s\n", migrate_reason_names[page_owner->last_migrate_reason]); page_ext_put(page_ext); @@ -826,7 +826,7 @@ static void init_pages_in_zone(struct zone *zone) =20 /* Found early allocated page */ __update_page_owner_handle(page, early_handle, 0, 0, - -1, local_clock(), current->pid, + MR_NEVER, local_clock(), current->pid, current->tgid, current->comm); count++; ext_put_continue: diff --git a/scripts/gdb/linux/page_owner.py b/scripts/gdb/linux/page_owner= .py index 8e713a09cfe7..eeabaeed438b 100644 --- a/scripts/gdb/linux/page_owner.py +++ b/scripts/gdb/linux/page_owner.py @@ -34,6 +34,7 @@ class DumpPageOwner(gdb.Command): max_pfn =3D None p_ops =3D None migrate_reason_names =3D None + mr_never =3D None =20 def __init__(self): super(DumpPageOwner, self).__init__("lx-dump-page-owner", gdb.COMM= AND_SUPPORT) @@ -65,6 +66,7 @@ class DumpPageOwner(gdb.Command): self.max_pfn =3D int(gdb.parse_and_eval("max_pfn")) self.page_ext_size =3D int(gdb.parse_and_eval("page_ext_size")) self.migrate_reason_names =3D gdb.parse_and_eval('migrate_reason_n= ames') + self.mr_never =3D int(gdb.parse_and_eval('MR_NEVER')) =20 def page_ext_invalid(self, page_ext): if page_ext =3D=3D gdb.Value(0): @@ -138,7 +140,7 @@ class DumpPageOwner(gdb.Command): else: gdb.write('page last free stack trace:\n') stackdepot.stack_depot_print(page_owner["free_handle"]) - if page_owner['last_migrate_reason'] !=3D -1: + if page_owner['last_migrate_reason'] !=3D self.mr_never: gdb.write('page has been migrated, last migrate reason: %s\n' = % self.migrate_reason_names[page_owner['last_migrate_reason']]) =20 def read_page_owner(self): --=20 2.43.0 From nobody Sat Jul 25 20:46:40 2026 Received: from out-174.mta0.migadu.com (out-174.mta0.migadu.com [91.218.175.174]) (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 AC47B370D65 for ; Tue, 14 Jul 2026 01:51:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993916; cv=none; b=dtaLHSKQxGYZy+HCRNJxRAJSMPhJQWnxCQJOH72dkB2O6B5wwBKRyZoKYwWYKgqJ5Qy74l3GxrWkp0/DK/RTUhR+AR2ShUjgjQwJpNGXKUTMDplqKg48h6+bsw4kBlTS9del1bvWdGKH3pZxIk1XbI3R2j6hIwufrObS6Sf44gw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993916; c=relaxed/simple; bh=VoBsS2ucqxifxCXJEAy/K3N2GGojoKYlHYaDkotORZo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UeOFbZwAYXfpjWVyuagZ9BqLR2pukwn/hBksR0BH19EOVKdiVkwmtuVphUUJZ4jUGlBKa6P8q6/ubPgAX1wXANnX1qd3BufS/quJYTkBOrXCyMaDzzU2l0cYYQUtd0yo69YbXD+X3JfUrBia1+8z0pxGNQZwhEiWlkTLTPNVaMk= 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=UH3DqNgy; arc=none smtp.client-ip=91.218.175.174 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="UH3DqNgy" 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=1783993912; 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=xUx+s70tFZfR5P8hN22+GO33VPB5qSBTtuJoi4AHZXY=; b=UH3DqNgyeHy0JYLTpNGlLQ4bJBub8FkBLmfx4x8chTFKbSyRMde7Ckon8t8hMPIVpV1ZRn 3IulmYQ+EyvNFZZoFWzqQGfTCCXAdJ0CXXXerO75/7kvSYPN+EfqprFZ0FalsK+cUKMgf8 +qOJYVWReHTF+XIPIbhnbffMQNh4oGg= From: Ye Liu To: Muchun Song , Oscar Salvador , Andrew Morton , David Hildenbrand , Steven Rostedt , Masami Hiramatsu , Vlastimil Babka Cc: Ye Liu , Zi Yan , Lorenzo Stoakes , Matthew Brost , Joshua Hahn , Rakie Kim , Byungchul Park , Gregory Price , Ying Huang , Alistair Popple , "Liam R. Howlett" , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Mathieu Desnoyers , Brendan Jackman , Johannes Weiner , linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Subject: [PATCH v6 3/9] mm: use enum migrate_reason instead of int for migration reason parameters Date: Tue, 14 Jul 2026 09:51:02 +0800 Message-ID: <20260714015117.78351-4-ye.liu@linux.dev> In-Reply-To: <20260714015117.78351-1-ye.liu@linux.dev> References: <20260714015117.78351-1-ye.liu@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 all 'int reason' function parameters that carry migrate_reason values with the proper 'enum migrate_reason' type. This makes the intent explicit and leverages compiler type checking. The affected subsystems are: - page_owner: __folio_set_owner_migrate_reason(), folio_set_owner_migrate_reason() - migrate: migrate_pages(), migrate_pages_sync(), migrate_pages_batch(), migrate_folios_move(), migrate_hugetlbs(), unmap_and_move_huge_page() - hugetlb: move_hugetlb_state(), htlb_allow_alloc_fallback() - trace: mm_migrate_pages and mm_migrate_pages_start events The 'short last_migrate_reason' struct field and internal helper parameter in page_owner are intentionally left as 'short' since they store per-page metadata where size matters. No functional change. Signed-off-by: Ye Liu Reviewed-by: Zi Yan Reviewed-by: Vlastimil Babka (SUSE) Reviewed-by: Lorenzo Stoakes Acked-by: David Hildenbrand (Arm) --- Changes in v6: - Drop unnecessary 'extern' from __folio_set_owner_migrate_reason() declaration in page_owner.h. - Adjust the indentation. - Link: https://lore.kernel.org/all/20260701061101.344679-4-ye.liu@linux.de= v/ include/linux/hugetlb.h | 9 +++++---- include/linux/migrate.h | 8 +++++--- include/linux/page_owner.h | 7 ++++--- include/trace/events/migrate.h | 8 ++++---- mm/hugetlb.c | 3 ++- mm/migrate.c | 12 ++++++------ mm/page_owner.c | 2 +- 7 files changed, 27 insertions(+), 22 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 2abaf99321e9..d6967fc94a49 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -154,7 +154,8 @@ long hugetlb_unreserve_pages(struct inode *inode, long = start, long end, bool folio_isolate_hugetlb(struct folio *folio, struct list_head *list); int get_hwpoison_hugetlb_folio(struct folio *folio, bool *hugetlb, bool un= poison); void folio_putback_hugetlb(struct folio *folio); -void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, = int reason); +void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, + enum migrate_reason reason); void hugetlb_fix_reserve_counts(struct inode *inode); extern struct mutex *hugetlb_fault_mutex_table; u32 hugetlb_fault_mutex_hash(struct address_space *mapping, pgoff_t idx); @@ -424,7 +425,7 @@ static inline void folio_putback_hugetlb(struct folio *= folio) } =20 static inline void move_hugetlb_state(struct folio *old_folio, - struct folio *new_folio, int reason) + struct folio *new_folio, enum migrate_reason reason) { } =20 @@ -956,7 +957,7 @@ static inline gfp_t htlb_modify_alloc_mask(struct hstat= e *h, gfp_t gfp_mask) return modified_mask; } =20 -static inline bool htlb_allow_alloc_fallback(int reason) +static inline bool htlb_allow_alloc_fallback(enum migrate_reason reason) { bool allowed_fallback =3D false; =20 @@ -1238,7 +1239,7 @@ static inline gfp_t htlb_modify_alloc_mask(struct hst= ate *h, gfp_t gfp_mask) return 0; } =20 -static inline bool htlb_allow_alloc_fallback(int reason) +static inline bool htlb_allow_alloc_fallback(enum migrate_reason reason) { return false; } diff --git a/include/linux/migrate.h b/include/linux/migrate.h index d5af2b7f577b..78424b3824c2 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -57,8 +57,9 @@ void putback_movable_pages(struct list_head *l); int migrate_folio(struct address_space *mapping, struct folio *dst, struct folio *src, enum migrate_mode mode); int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free, - unsigned long private, enum migrate_mode mode, int reason, - unsigned int *ret_succeeded); + unsigned long private, enum migrate_mode mode, + enum migrate_reason reason, + unsigned int *ret_succeeded); struct folio *alloc_migration_target(struct folio *src, unsigned long priv= ate); bool isolate_movable_ops_page(struct page *page, isolate_mode_t mode); bool isolate_folio_to_list(struct folio *folio, struct list_head *list); @@ -77,7 +78,8 @@ int set_movable_ops(const struct movable_operations *ops,= enum pagetype type); static inline void putback_movable_pages(struct list_head *l) {} static inline int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free, unsigned long private, - enum migrate_mode mode, int reason, unsigned int *ret_succeeded) + enum migrate_mode mode, enum migrate_reason reason, + unsigned int *ret_succeeded) { return -ENOSYS; } static inline struct folio *alloc_migration_target(struct folio *src, unsigned long private) diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h index 3328357f6dba..8188ddc5c412 100644 --- a/include/linux/page_owner.h +++ b/include/linux/page_owner.h @@ -3,6 +3,7 @@ #define __LINUX_PAGE_OWNER_H =20 #include +#include =20 #ifdef CONFIG_PAGE_OWNER extern struct static_key_false page_owner_inited; @@ -14,7 +15,7 @@ extern void __set_page_owner(struct page *page, extern void __split_page_owner(struct page *page, int old_order, int new_order); extern void __folio_copy_owner(struct folio *newfolio, struct folio *old); -extern void __folio_set_owner_migrate_reason(struct folio *folio, int reas= on); +void __folio_set_owner_migrate_reason(struct folio *folio, enum migrate_re= ason reason); extern void __dump_page_owner(const struct page *page); extern void pagetypeinfo_showmixedcount_print(struct seq_file *m, pg_data_t *pgdat, struct zone *zone); @@ -43,7 +44,7 @@ static inline void folio_copy_owner(struct folio *newfoli= o, struct folio *old) if (static_branch_unlikely(&page_owner_inited)) __folio_copy_owner(newfolio, old); } -static inline void folio_set_owner_migrate_reason(struct folio *folio, int= reason) +static inline void folio_set_owner_migrate_reason(struct folio *folio, enu= m migrate_reason reason) { if (static_branch_unlikely(&page_owner_inited)) __folio_set_owner_migrate_reason(folio, reason); @@ -68,7 +69,7 @@ static inline void split_page_owner(struct page *page, in= t old_order, static inline void folio_copy_owner(struct folio *newfolio, struct folio *= folio) { } -static inline void folio_set_owner_migrate_reason(struct folio *folio, int= reason) +static inline void folio_set_owner_migrate_reason(struct folio *folio, enu= m migrate_reason reason) { } static inline void dump_page_owner(const struct page *page) diff --git a/include/trace/events/migrate.h b/include/trace/events/migrate.h index 11bc0aa14c7e..15ee2ef201b5 100644 --- a/include/trace/events/migrate.h +++ b/include/trace/events/migrate.h @@ -52,7 +52,7 @@ TRACE_EVENT(mm_migrate_pages, TP_PROTO(unsigned long succeeded, unsigned long failed, unsigned long thp_succeeded, unsigned long thp_failed, unsigned long thp_split, unsigned long large_folio_split, - enum migrate_mode mode, int reason), + enum migrate_mode mode, enum migrate_reason reason), =20 TP_ARGS(succeeded, failed, thp_succeeded, thp_failed, thp_split, large_folio_split, mode, reason), @@ -65,7 +65,7 @@ TRACE_EVENT(mm_migrate_pages, __field( unsigned long, thp_split) __field( unsigned long, large_folio_split) __field( enum migrate_mode, mode) - __field( int, reason) + __field( enum migrate_reason, reason) ), =20 TP_fast_assign( @@ -92,13 +92,13 @@ TRACE_EVENT(mm_migrate_pages, =20 TRACE_EVENT(mm_migrate_pages_start, =20 - TP_PROTO(enum migrate_mode mode, int reason), + TP_PROTO(enum migrate_mode mode, enum migrate_reason reason), =20 TP_ARGS(mode, reason), =20 TP_STRUCT__entry( __field(enum migrate_mode, mode) - __field(int, reason) + __field(enum migrate_reason, reason) ), =20 TP_fast_assign( diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 571212b80835..17732d1fdc5e 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -7182,7 +7182,8 @@ void folio_putback_hugetlb(struct folio *folio) folio_put(folio); } =20 -void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, = int reason) +void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, + enum migrate_reason reason) { struct hstate *h =3D folio_hstate(old_folio); =20 diff --git a/mm/migrate.c b/mm/migrate.c index d9b23909d716..49e10feeb094 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1469,7 +1469,7 @@ static int migrate_folio_move(free_folio_t put_new_fo= lio, unsigned long private, static int unmap_and_move_huge_page(new_folio_t get_new_folio, free_folio_t put_new_folio, unsigned long private, struct folio *src, int force, enum migrate_mode mode, - int reason, struct list_head *ret) + enum migrate_reason reason, struct list_head *ret) { struct folio *dst; int rc =3D -EAGAIN; @@ -1626,7 +1626,7 @@ struct migrate_pages_stats { */ static int migrate_hugetlbs(struct list_head *from, new_folio_t get_new_fo= lio, free_folio_t put_new_folio, unsigned long private, - enum migrate_mode mode, int reason, + enum migrate_mode mode, enum migrate_reason reason, struct migrate_pages_stats *stats, struct list_head *ret_folios) { @@ -1716,7 +1716,7 @@ static int migrate_hugetlbs(struct list_head *from, n= ew_folio_t get_new_folio, static void migrate_folios_move(struct list_head *src_folios, struct list_head *dst_folios, free_folio_t put_new_folio, unsigned long private, - enum migrate_mode mode, int reason, + enum migrate_mode mode, enum migrate_reason reason, struct list_head *ret_folios, struct migrate_pages_stats *stats, int *retry, int *thp_retry, int *nr_failed, @@ -1799,7 +1799,7 @@ static void migrate_folios_undo(struct list_head *src= _folios, */ static int migrate_pages_batch(struct list_head *from, new_folio_t get_new_folio, free_folio_t put_new_folio, - unsigned long private, enum migrate_mode mode, int reason, + unsigned long private, enum migrate_mode mode, enum migrate_reason reaso= n, struct list_head *ret_folios, struct list_head *split_folios, struct migrate_pages_stats *stats, int nr_pass) { @@ -2011,7 +2011,7 @@ static int migrate_pages_batch(struct list_head *from, =20 static int migrate_pages_sync(struct list_head *from, new_folio_t get_new_= folio, free_folio_t put_new_folio, unsigned long private, - enum migrate_mode mode, int reason, + enum migrate_mode mode, enum migrate_reason reason, struct list_head *ret_folios, struct list_head *split_folios, struct migrate_pages_stats *stats) { @@ -2088,7 +2088,7 @@ static int migrate_pages_sync(struct list_head *from,= new_folio_t get_new_folio, */ int migrate_pages(struct list_head *from, new_folio_t get_new_folio, free_folio_t put_new_folio, unsigned long private, - enum migrate_mode mode, int reason, unsigned int *ret_succeeded) + enum migrate_mode mode, enum migrate_reason reason, unsigned int *ret_su= cceeded) { int rc, rc_gather; int nr_pages; diff --git a/mm/page_owner.c b/mm/page_owner.c index c2f43ab860eb..4e352941a6e2 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -345,7 +345,7 @@ noinline void __set_page_owner(struct page *page, unsig= ned short order, inc_stack_record_count(handle, gfp_mask, 1 << order); } =20 -void __folio_set_owner_migrate_reason(struct folio *folio, int reason) +void __folio_set_owner_migrate_reason(struct folio *folio, enum migrate_re= ason reason) { struct page_ext *page_ext =3D page_ext_get(&folio->page); struct page_owner *page_owner; --=20 2.43.0 From nobody Sat Jul 25 20:46:40 2026 Received: from out-170.mta0.migadu.com (out-170.mta0.migadu.com [91.218.175.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 11EAE372058 for ; Tue, 14 Jul 2026 01:51:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993919; cv=none; b=k9fjPISeZPpyW6D8AEylyLLOdB+CWKq2Omki54hElzRC+ATmI4eO6NXyTlGKpQyCP/y7rFxqo7QyxMNGaf31PnmLr3ZuWT8NdMTD47tZx+vWUAsZgBW2MK4qWAvj/A8+e+4Pt/ckUjRJ9i1AaNlORMwSceWcqjQOsurGEubp9r8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993919; c=relaxed/simple; bh=e0PbK+wK92Zv6TvIhjVBvA2T+MJGCVXfOYBXEKewRWs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TYoRIh5EMkN5Qe2c3X2LNciMPzlyk5btunizyJ6ZY16vrbqZQuJEFIlC6sigcfaywO3HC6At0CPnVKTtQxOxq1xrejvLQql1KINXf5F7/J9cWF17JwcrbT0LxA3DxC71zHqrRmNofzSmFWgMEX2wRBSOpw13nd6SyfTqlWY6kUE= 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=VDaeVNHK; arc=none smtp.client-ip=91.218.175.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="VDaeVNHK" 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=1783993915; 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=x7l7Cu37ztLHTqXl9+24GTeEvM65Yy8Y6kuKnfhmUgo=; b=VDaeVNHK+rzrDKN2cUcePBSwvPQv4gQChSDROMeh/IDfcf0524K+aEn9CaldetVKqLuiTo cJ2JddY6eVAvm3KEOVJtRG5oeFLglna/ghidCotyBiWlCDy6KWJvGl59Z+UNWX9ocr3Afx H52xXEXZ779qjMM0gTO/7kFVsPFQAvU= From: Ye Liu To: Andrew Morton , Vlastimil Babka Cc: Ye Liu , Zi Yan , Suren Baghdasaryan , Michal Hocko , Brendan Jackman , Johannes Weiner , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 4/9] mm/page_owner: hoist CONFIG_MEMCG to function level for print_page_owner_memcg() Date: Tue, 14 Jul 2026 09:51:03 +0800 Message-ID: <20260714015117.78351-5-ye.liu@linux.dev> In-Reply-To: <20260714015117.78351-1-ye.liu@linux.dev> References: <20260714015117.78351-1-ye.liu@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" The print_page_owner_memcg() function has CONFIG_MEMCG guarding its entire body via #ifdef inside the function, which leaves a no-op { return ret; } when the config is disabled. Hoist the #ifdef to the top level so the real implementation and the empty stub are two clearly separated definitions. No functional change. Signed-off-by: Ye Liu Reviewed-by: Zi Yan Reviewed-by: Vlastimil Babka (SUSE) --- mm/page_owner.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index 4e352941a6e2..fe2bf2274d8a 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -522,13 +522,13 @@ void pagetypeinfo_showmixedcount_print(struct seq_fil= e *m, seq_putc(m, '\n'); } =20 +#ifdef CONFIG_MEMCG /* * Looking for memcg information and print it out */ static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret, struct page *page) { -#ifdef CONFIG_MEMCG unsigned long memcg_data; struct mem_cgroup *memcg; bool online; @@ -556,10 +556,16 @@ static inline int print_page_owner_memcg(char *kbuf, = size_t count, int ret, name); out_unlock: rcu_read_unlock(); -#endif /* CONFIG_MEMCG */ =20 return ret; } +#else +static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret, + struct page *page) +{ + return ret; +} +#endif =20 static ssize_t print_page_owner(char __user *buf, size_t count, unsigned long pfn, --=20 2.43.0 From nobody Sat Jul 25 20:46:40 2026 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (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 83CF3371887 for ; Tue, 14 Jul 2026 01:52:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993923; cv=none; b=QNAetWe7BG8hQJ6A0+crdMs0Og5TEtyhG5En4iA4hnqZzX6Y3VewBepsYKmSYKWua/H2OgfwpcCGt5VffXIV/x9wig/ins7IUlG/OQpX/0Pz/Q049ZOSmPZqICMopU890GxODXHQfwUq1nJqrLW6dK+x1SuHqPjxSmz5+hjfQ84= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993923; c=relaxed/simple; bh=7FBU8wLQenp8S4RfUBTR/9Bb7RAV7+7hhhc02OaqVjo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=c0xzUNnpSkPGuEdMelpkmb1We3451kJMTO+3I3+M4H2U/qDM4EU0fz7312lf91yl7a8t6LRvVboib1dds/vNE7oI/Q5gOZDLzZF+qLtUYcIv4Ac7mg60C7tcc1DlI/Q5feQPKCKJ+3fT/Py/VKdnVDvRruYH8ij1dJM/WKp1m7w= 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=NDmwAxeg; arc=none smtp.client-ip=91.218.175.185 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="NDmwAxeg" 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=1783993919; 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=hMPk4xo0goYwl32b+O7Fi24CGRO5SYSFgHPQLi10p/I=; b=NDmwAxegFBJvW/6KgfXr4KpsbluuEfl37QztIvImDOCXBwM6S92epmL0lEqi23eWeuKpVD LgcTfRq5yd/8NVj/p4r1y6TMB7m/4DCbMstBe8+Ad2cLvNmRkvkAi8LVmX47LD78QOAjN3 yB0Wv6BkCFxgHguaP9h+rP9wiPsKaog= From: Ye Liu To: Andrew Morton , Vlastimil Babka Cc: Ye Liu , Zi Yan , Suren Baghdasaryan , Michal Hocko , Brendan Jackman , Johannes Weiner , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 5/9] mm/page_owner: add missing newline to count_threshold format string Date: Tue, 14 Jul 2026 09:51:04 +0800 Message-ID: <20260714015117.78351-6-ye.liu@linux.dev> In-Reply-To: <20260714015117.78351-1-ye.liu@linux.dev> References: <20260714015117.78351-1-ye.liu@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" The DEFINE_SIMPLE_ATTRIBUTE format string for page_owner_threshold_fops is missing a trailing \n. simple_attr_read() uses scnprintf() with the format string, which does not append a newline, so reading /sys/kernel/debug/page_owner_stacks/count_threshold produces output without a terminating newline. Add the missing \n to match the standard debugfs attribute convention. Signed-off-by: Ye Liu Reviewed-by: Zi Yan Reviewed-by: Vlastimil Babka (SUSE) --- mm/page_owner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index fe2bf2274d8a..7520718f63f1 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -974,7 +974,7 @@ static int page_owner_threshold_set(void *data, u64 val) } =20 DEFINE_SIMPLE_ATTRIBUTE(page_owner_threshold_fops, &page_owner_threshold_g= et, - &page_owner_threshold_set, "%llu"); + &page_owner_threshold_set, "%llu\n"); =20 =20 static int __init pageowner_init(void) --=20 2.43.0 From nobody Sat Jul 25 20:46:40 2026 Received: from out-188.mta0.migadu.com (out-188.mta0.migadu.com [91.218.175.188]) (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 B347A371065 for ; Tue, 14 Jul 2026 01:52:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993926; cv=none; b=n7qz+F60mFkO2OhWHnJKy7gx+XZHUp4Jy4UjtgoNmdAOSYzUBPP7MFSU+BnqCmevWAZBdLJtbmMXxu2Y1boU/PNEDAsPoJbDu6R6SfbKyy8y3YvjpdreHIYyTTw/idPvttHAN9QZhFSiUtnYKGD38PvXMLTKMkfD0lbnYtnv0GY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993926; c=relaxed/simple; bh=BIfewT+/Ss9qfklObQRxeoSboXrNP/ZMldhPIfGq514=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iFi/2vHrrTnvixv7DYbBS6JyZnykl/HTLBRzXWmXWjdYGwXQ7DXZcY4bjH5lyCYOPzc8ojG58eoaPz0dRKBwJsA4qFpGyVzHFuxwMgaF1V9TD7kLp1sASmKZ8Fpd1uGI5TUO97kMME3LV1K7iJaaqUMh31m7N/A5+KExjOUYn+Q= 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=fqfByGfY; arc=none smtp.client-ip=91.218.175.188 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="fqfByGfY" 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=1783993923; 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=7AeQBR8Jr8+xBr3Mb/Jq7ZoDTM1Fuhu9AGQLRB/s3dg=; b=fqfByGfYsNTihfrSrwhbwzZuoH3xxwVyI/5JThH+K2q/+S9OM5Ma7Q+cUJ5wJL3qsaVQ5z m3K3G/vVFDw8SXDZ7EcNv9hwp7FN+cJFsz4NqChgwMYjDyCzmownulJMQidYu37fUjyskH SO5zlTYhqwlwyEKSB19qlNCNHyvsrIA= From: Ye Liu To: Andrew Morton , Vlastimil Babka Cc: Ye Liu , Zi Yan , Suren Baghdasaryan , Michal Hocko , Brendan Jackman , Johannes Weiner , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 6/9] mm/page_owner: move free_ts_nsec output to free section in __dump_page_owner() Date: Tue, 14 Jul 2026 09:51:05 +0800 Message-ID: <20260714015117.78351-7-ye.liu@linux.dev> In-Reply-To: <20260714015117.78351-1-ye.liu@linux.dev> References: <20260714015117.78351-1-ye.liu@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" The free_ts_nsec field is a free-event timestamp, but it was printed in the allocation summary line alongside ts_nsec (allocation time). Move it to the free section where it logically belongs, together with free_pid and free_tgid. This also makes __dump_page_owner() consistent with print_page_owner(), which only prints ts_nsec in the allocation summary. The output now groups all free-related information (pid, tgid, timestamp, stack trace) in one place. No functional change except output formatting. Signed-off-by: Ye Liu Acked-by: Zi Yan Reviewed-by: Vlastimil Babka (SUSE) --- mm/page_owner.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index 7520718f63f1..84eb44459478 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -653,10 +653,10 @@ void __dump_page_owner(const struct page *page) else pr_alert("page_owner tracks the page as freed\n"); =20 - pr_alert("page last allocated via order %u, migratetype %s, gfp_mask %#x(= %pGg), pid %d, tgid %d (%s), ts %llu, free_ts %llu\n", + pr_alert("page last allocated via order %u, migratetype %s, gfp_mask %#x(= %pGg), pid %d, tgid %d (%s), ts %llu\n", page_owner->order, migratetype_names[mt], gfp_mask, &gfp_mask, page_owner->pid, page_owner->tgid, page_owner->comm, - page_owner->ts_nsec, page_owner->free_ts_nsec); + page_owner->ts_nsec); =20 handle =3D READ_ONCE(page_owner->handle); if (!handle) @@ -668,8 +668,9 @@ void __dump_page_owner(const struct page *page) if (!handle) { pr_alert("page_owner free stack trace missing\n"); } else { - pr_alert("page last free pid %d tgid %d stack trace:\n", - page_owner->free_pid, page_owner->free_tgid); + pr_alert("page last free pid %d tgid %d ts %llu stack trace:\n", + page_owner->free_pid, page_owner->free_tgid, + page_owner->free_ts_nsec); stack_depot_print(handle); } =20 --=20 2.43.0 From nobody Sat Jul 25 20:46:40 2026 Received: from out-188.mta0.migadu.com (out-188.mta0.migadu.com [91.218.175.188]) (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 C8AC036F8E9 for ; Tue, 14 Jul 2026 01:52:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993930; cv=none; b=d/dTlwpDaVpHWd5byAHna3qJZeW1jW27ZVC0yq596rKsPyUmUxhnXP0K62eO1FyK1/JUXSoXqaYS8FaVqLhLNNTUcX33Es6uCjnGeDgjZFMCNmLwEOhs3a9CRa+tHpRG3EvuTFv1WPA3CYxsu5TXUaqs0cYHly5i+2lwXnZpBTo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993930; c=relaxed/simple; bh=sMNeGAPl/p1ucHzZYm/QlX2HMkZ2cQ5LHWIo6+yI/Fg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kDRUxU3nkgVCiqy1cvHPYgeyFiNXVAVrbaImdNDbRA2AhC6kITzgT9L8J7OMpCnAbzfkQYPFX+WRaqpLLtUzz6iMQGgVrXwbZc0ocwDQoR/AQokQP9BZWSD2Bxic2DPLz86lID3IG6F2ppo9uZL53ymW3BvpZf/Fqz4rivZmyHg= 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=c7lduUdd; arc=none smtp.client-ip=91.218.175.188 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="c7lduUdd" 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=1783993926; 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=/hUCwkjzO8JlsV4HHcqpi2o/7R7QmnmDlK+R08kvU+c=; b=c7lduUddicEIKFtK1ufOalDWkjpj1e6uQ0u1KARNsdMvK19yMSiSGT2sZaIMYsO5FP6G8E wcbXw/8O16sW4mlSuRh1ce0CoIOioW9C/4EKp5p1Em1pS8PXs64yu8f0XJj4fNNIvDESdY /VkCeP/32yXCzDw3/2i54pTCqTU+t+o= From: Ye Liu To: Andrew Morton , Vlastimil Babka Cc: Ye Liu , Zi Yan , Suren Baghdasaryan , Michal Hocko , Brendan Jackman , Johannes Weiner , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 7/9] mm/page_owner: drop redundant page_owner prefix from static symbols Date: Tue, 14 Jul 2026 09:51:06 +0800 Message-ID: <20260714015117.78351-8-ye.liu@linux.dev> In-Reply-To: <20260714015117.78351-1-ye.liu@linux.dev> References: <20260714015117.78351-1-ye.liu@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" All of these symbols are file-scoped (static) in page_owner.c, so the page_owner_ prefix is pure noise. Rename them to shorter, still-clear names: page_owner_stack_op -> stack_op page_owner_stack_open -> stack_open page_owner_stack_fops -> stack_fops page_owner_pages_threshold -> pages_threshold page_owner_threshold_get -> threshold_get page_owner_threshold_set -> threshold_set page_owner_threshold_fops -> threshold_fops No functional change. Signed-off-by: Ye Liu Acked-by: Zi Yan Reviewed-by: Vlastimil Babka (SUSE) --- mm/page_owner.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index 84eb44459478..46a933f9c229 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -894,7 +894,7 @@ static void *stack_next(struct seq_file *m, void *v, lo= ff_t *ppos) return stack; } =20 -static unsigned long page_owner_pages_threshold; +static unsigned long pages_threshold; =20 static int stack_print(struct seq_file *m, void *v) { @@ -911,7 +911,7 @@ static int stack_print(struct seq_file *m, void *v) nr_base_pages =3D refcount_read(&stack_record->count) - 1; =20 if (ctx->flags & STACK_PRINT_FLAG_PAGES && - (nr_base_pages < 1 || nr_base_pages < page_owner_pages_threshold)) + (nr_base_pages < 1 || nr_base_pages < pages_threshold)) return 0; =20 if (ctx->flags & STACK_PRINT_FLAG_STACK) { @@ -933,16 +933,16 @@ static void stack_stop(struct seq_file *m, void *v) { } =20 -static const struct seq_operations page_owner_stack_op =3D { +static const struct seq_operations stack_op =3D { .start =3D stack_start, .next =3D stack_next, .stop =3D stack_stop, .show =3D stack_print }; =20 -static int page_owner_stack_open(struct inode *inode, struct file *file) +static int stack_open(struct inode *inode, struct file *file) { - int ret =3D seq_open_private(file, &page_owner_stack_op, + int ret =3D seq_open_private(file, &stack_op, sizeof(struct stack_print_ctx)); =20 if (!ret) { @@ -955,28 +955,26 @@ static int page_owner_stack_open(struct inode *inode,= struct file *file) return ret; } =20 -static const struct file_operations page_owner_stack_fops =3D { - .open =3D page_owner_stack_open, +static const struct file_operations stack_fops =3D { + .open =3D stack_open, .read =3D seq_read, .llseek =3D seq_lseek, .release =3D seq_release_private, }; =20 -static int page_owner_threshold_get(void *data, u64 *val) +static int threshold_get(void *data, u64 *val) { - *val =3D READ_ONCE(page_owner_pages_threshold); + *val =3D READ_ONCE(pages_threshold); return 0; } =20 -static int page_owner_threshold_set(void *data, u64 val) +static int threshold_set(void *data, u64 val) { - WRITE_ONCE(page_owner_pages_threshold, val); + WRITE_ONCE(pages_threshold, val); return 0; } =20 -DEFINE_SIMPLE_ATTRIBUTE(page_owner_threshold_fops, &page_owner_threshold_g= et, - &page_owner_threshold_set, "%llu\n"); - +DEFINE_SIMPLE_ATTRIBUTE(threshold_fops, &threshold_get, &threshold_set, "%= llu\n"); =20 static int __init pageowner_init(void) { @@ -992,17 +990,17 @@ static int __init pageowner_init(void) debugfs_create_file("show_stacks", 0400, dir, (void *)(STACK_PRINT_FLAG_STACK | STACK_PRINT_FLAG_PAGES), - &page_owner_stack_fops); + &stack_fops); debugfs_create_file("show_handles", 0400, dir, (void *)(STACK_PRINT_FLAG_HANDLE | STACK_PRINT_FLAG_PAGES), - &page_owner_stack_fops); + &stack_fops); debugfs_create_file("show_stacks_handles", 0400, dir, (void *)(STACK_PRINT_FLAG_STACK | STACK_PRINT_FLAG_HANDLE), - &page_owner_stack_fops); + &stack_fops); debugfs_create_file("count_threshold", 0600, dir, NULL, - &page_owner_threshold_fops); + &threshold_fops); return 0; } late_initcall(pageowner_init) --=20 2.43.0 From nobody Sat Jul 25 20:46:40 2026 Received: from out-181.mta0.migadu.com (out-181.mta0.migadu.com [91.218.175.181]) (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 20AE3373BF1 for ; Tue, 14 Jul 2026 01:52:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993933; cv=none; b=idKaE1CreMBtwtioD/OKJoGWi6HqvqyPGeWTEtmB/sAZwI5F/0y6dHSTrX1B6PQ/u2Nn6HTLyRkZvaQl9muZPSdwq2uZxQAkd7vh/ntfKN9KQikbHBigQiWMu3OfQ8IW2Pm3S07ypLAHlgO1IJgkdUiBZfjQ5f62x2wulTTKBU8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993933; c=relaxed/simple; bh=I0jU8AraJ2sL+WDXF9gv4pktBtYcNqcS4dgWYDNNDWo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NQd1GYHUdInktl3DKyWsNqTs9UEAQGtQ4eCvS/nm+NWkqCnyNcNGzCiR8a7Eum/7k81EXveiua5qyNm2iXLh/KRPXbYxN/Z72upGFkC9l/Hn7cv4zD94eMIu1soDdztEX2mxQ56aPpvW6hmnlWfgSxY+qnl2zSQMO3mOWw/Jj0M= 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=U08nGuag; arc=none smtp.client-ip=91.218.175.181 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="U08nGuag" 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=1783993930; 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=Zi8sMOqCJW2NCRhuASX5GgkHm8VKvEUdMiR4+SQo7LU=; b=U08nGuagzbVhLLarcP6Ht3kvNTZeXYqu3T5PvbGybt6QkW43Jh4P2dRv0/rY/wJErmKNrS pNZXrhPoV3IehqV6DD/WE8oX+Gf8zyotNtcam06UrfbSuj04VyD/ZiMMyC19BYOCtvHb1H G+APLQqEcI61CRRjWSjiJmTtRPeT/Z4= From: Ye Liu To: Andrew Morton , Vlastimil Babka Cc: Ye Liu , Zi Yan , Suren Baghdasaryan , Michal Hocko , Brendan Jackman , Johannes Weiner , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 8/9] mm/page_owner: clamp skip_buddy_pages() PFN advance at MAX_ORDER_NR_PAGES boundary Date: Tue, 14 Jul 2026 09:51:07 +0800 Message-ID: <20260714015117.78351-9-ye.liu@linux.dev> In-Reply-To: <20260714015117.78351-1-ye.liu@linux.dev> References: <20260714015117.78351-1-ye.liu@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" The lockless buddy_order_unsafe() read can return a garbage order value if the page is concurrently allocated between the PageBuddy check and the private read. If this bogus order is <=3D MAX_PAGE_ORDER, skip_buddy_pages() would arbitrarily advance the PFN, potentially jumping past a MAX_ORDER_NR_PAGES boundary whose pfn_valid() check would have caught an offline memory section. In read_page_owner(), which relies solely on boundary-aligned pfn_valid() to guard pfn_to_page(), skipping the boundary could cause pfn_to_page() to access an unmapped mem_section. Clamp the advance so it never crosses the next MAX_ORDER_NR_PAGES boundary. This is safe for all three callers: the pageblock-iterating ones already handle boundary transitions in their outer loops, and for read_page_owner() the worst case is one extra PageBuddy check per 1024 pages when a bogus order would otherwise push past the boundary. Signed-off-by: Ye Liu Reviewed-by: Zi Yan Reviewed-by: Vlastimil Babka (SUSE) --- mm/page_owner.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index 46a933f9c229..2e3880053a34 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -428,6 +428,12 @@ void __folio_copy_owner(struct folio *newfolio, struct= folio *old) * to skip less than the full buddy block, but that is acceptable for page= owner * iteration purposes. * + * The lockless read of buddy_order_unsafe() can also return a garbage ord= er if + * the page is concurrently allocated and PageBuddy is cleared between the= check + * and the read. Clamp the advance at the next MAX_ORDER_NR_PAGES boundary= so + * that a bogus order cannot carry @pfn into an unvalidated memory section, + * which would break callers that rely on boundary-aligned pfn_valid() che= cks. + * * Return: true if the page was skipped (caller should continue its loop), * false if the page is not a buddy page and should be processed n= ormally. */ @@ -439,8 +445,12 @@ static inline bool skip_buddy_pages(unsigned long *pfn= , struct page *page) return false; =20 order =3D buddy_order_unsafe(page); - if (order <=3D MAX_PAGE_ORDER) - *pfn +=3D (1UL << order) - 1; + if (order <=3D MAX_PAGE_ORDER) { + unsigned long new_pfn =3D *pfn + (1UL << order); + unsigned long boundary =3D ALIGN(*pfn + 1, MAX_ORDER_NR_PAGES); + + *pfn =3D min(new_pfn, boundary) - 1; + } =20 return true; } --=20 2.43.0 From nobody Sat Jul 25 20:46:40 2026 Received: from out-171.mta0.migadu.com (out-171.mta0.migadu.com [91.218.175.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 E23FF372056 for ; Tue, 14 Jul 2026 01:52:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993937; cv=none; b=hz2oQztLIyfnOI5TY3VSZr6Ixr9q1famzkrLPNNwWRULRqMoV3v6NfCCGt0amutfRVC9FNvnhykdhqA2noZ51vjZAGMrAjASD/RpoJ6SAmXgc2thfy8PxK3HkvjDf+tjNjgMHe/ur5OLqL+0yJIgF+SKlefnMY+56DZH7At98aY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783993937; c=relaxed/simple; bh=idQ9hkZPaWO5XRXHfLYCRc8ylO1WiBswmcQ/5Ywr6FE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Nm/yLUB6GZomUk+9I9FqS1KS/0zf8cWxNKhlAX+hi+dknxnEZig/VO+Z873OQnP4qt1zXyb8EkEwSV+tg5rF0MlO+3eEbNogiuOxeJDI9RGsbBwfjyhjy1FIGY+7Mzn0a2eEWLRVoencEnFjmn63wC+VUohG8P+1Gg664EHuHoo= 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=phiRJC08; arc=none smtp.client-ip=91.218.175.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="phiRJC08" 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=1783993934; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2Pj2O1XV/iVkFDN8GVAoeYlkqg9Q6iDpIRfEcXtGxjw=; b=phiRJC08q5I5JcA3F6fMnZB1OyZRYKqEqiv6Y0aGluxJ7VzGnXQkfpPONgcPdItEWoGzZD 9BBqeYTV0ttmcWvgeZyk1QB1qPUFGkmxxSy0L2TEvXBiX/MMGMENJ1iuQ0M6Z7zXFyQ/31 vBthOxmjYMQXREFgpPs0km+9AM32NWE= From: Ye Liu To: Andrew Morton , Vlastimil Babka Cc: Ye Liu , Suren Baghdasaryan , Michal Hocko , Brendan Jackman , Johannes Weiner , Zi Yan , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 9/9] mm/page_owner: use memcg_data snapshot to avoid TOCTOU in print_page_owner_memcg() Date: Tue, 14 Jul 2026 09:51:08 +0800 Message-ID: <20260714015117.78351-10-ye.liu@linux.dev> In-Reply-To: <20260714015117.78351-1-ye.liu@linux.dev> References: <20260714015117.78351-1-ye.liu@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT print_page_owner_memcg() takes a snapshot of page->memcg_data via READ_ONCE at the top of the function and guards against tail pages and NULL memcg_data. However, it later calls two functions that re-read page->memcg_data locklessly: 1) page_memcg_check(page) =E2=80=94 re-reads page->memcg_data; 2) PageMemcgKmem(page) =E2=80=94 calls folio_memcg_kmem(), which re-reads folio->memcg_data and folio->page->compound_head, wrapping both in VM_BUG_ON assertions: VM_BUG_ON_PGFLAGS(PageTail(&folio->page), &folio->page); VM_BUG_ON_FOLIO(folio->memcg_data & MEMCG_DATA_OBJEXTS, folio); If the page is concurrently freed and reallocated as a THP tail page or a slab page between the initial guards and these later calls, the VM_BUG_ON assertions can fire on debug builds (CONFIG_DEBUG_VM=3Dy), causing a kernel panic. Fix both TOCTOU issues by using the memcg_data snapshot throughout: - Extract objcg from the snapshot via objcg =3D (void *)(memcg_data & ~OBJEXTS_FLAGS_MASK) instead of calling page_memcg_check(page); - Test (memcg_data & MEMCG_DATA_KMEM) instead of calling PageMemcgKmem(page), which is semantically equivalent: PageMemcgKmem()->folio_memcg_kmem()->folio->memcg_data & MEMCG_DATA_KMEM. - When memcg_data has MEMCG_DATA_OBJEXTS set, early-return after printing "Slab cache page\n" since objcg !=3D memcg for slab pages and there is no meaningful cgroup to look up. This avoids both TOCTOU windows and the assertions entirely. Signed-off-by: Ye Liu Reported-by: Sashiko Reviewed-by: Vlastimil Babka (SUSE) Reviewed-by: Zi Yan --- Changes in v6: - Rename patch to cover both TOCTOU fixes rather than only PageMemcgKmem(). - Also replace page_memcg_check(page) with extracting objcg from the memcg_data snapshot to fix a second TOCTOU issue. - Add early return for the MEMCG_DATA_OBJEXTS (slab) case since objcg !=3D memcg for slab pages and there is no cgroup to look up. - Update commit message to cover all changes. - Link: https://lore.kernel.org/all/20260701061101.344679-10-ye.liu@linux.d= ev/ mm/page_owner.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index 2e3880053a34..e18512a49e38 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -540,6 +540,7 @@ static inline int print_page_owner_memcg(char *kbuf, si= ze_t count, int ret, struct page *page) { unsigned long memcg_data; + struct obj_cgroup *objcg; struct mem_cgroup *memcg; bool online; char name[80]; @@ -549,11 +550,14 @@ static inline int print_page_owner_memcg(char *kbuf, = size_t count, int ret, if (!memcg_data || PageTail(page)) goto out_unlock; =20 - if (memcg_data & MEMCG_DATA_OBJEXTS) + if (memcg_data & MEMCG_DATA_OBJEXTS) { ret +=3D scnprintf(kbuf + ret, count - ret, "Slab cache page\n"); + goto out_unlock; + } =20 - memcg =3D page_memcg_check(page); + objcg =3D (void *)(memcg_data & ~OBJEXTS_FLAGS_MASK); + memcg =3D objcg ? obj_cgroup_memcg(objcg) : NULL; if (!memcg) goto out_unlock; =20 @@ -561,7 +565,7 @@ static inline int print_page_owner_memcg(char *kbuf, si= ze_t count, int ret, cgroup_name(memcg->css.cgroup, name, sizeof(name)); ret +=3D scnprintf(kbuf + ret, count - ret, "Charged %sto %smemcg %s\n", - PageMemcgKmem(page) ? "(via objcg) " : "", + (memcg_data & MEMCG_DATA_KMEM) ? "(via objcg) " : "", online ? "" : "offline ", name); out_unlock: --=20 2.43.0