| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/01 07:16 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch consists of refactoring (changing 'int reason' to 'enum migrate_reason reason', extracting 'skip_buddy_pages', moving #ifdefs), tracepoint updates, and minor debugfs output formatting changes (adding a newline to a simple attribute). It does not functionally alter the execution flow of the kernel.",
"WorthFuzzing": false
} |
| 1/1 | 2026/07/01 07:16 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 6b07bb2671cd0ea0b90b40a4cc114b008d212e99\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Wed Jul 1 07:16:32 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h\nindex 2abaf99321e90d..fa828232dfcc18 100644\n--- a/include/linux/hugetlb.h\n+++ b/include/linux/hugetlb.h\n@@ -154,7 +154,8 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end,\n bool folio_isolate_hugetlb(struct folio *folio, struct list_head *list);\n int get_hwpoison_hugetlb_folio(struct folio *folio, bool *hugetlb, bool unpoison);\n void folio_putback_hugetlb(struct folio *folio);\n-void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, int reason);\n+void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio,\n+\t\t\tenum migrate_reason reason);\n void hugetlb_fix_reserve_counts(struct inode *inode);\n extern struct mutex *hugetlb_fault_mutex_table;\n u32 hugetlb_fault_mutex_hash(struct address_space *mapping, pgoff_t idx);\n@@ -424,7 +425,7 @@ static inline void folio_putback_hugetlb(struct folio *folio)\n }\n \n static inline void move_hugetlb_state(struct folio *old_folio,\n-\t\t\t\t\tstruct folio *new_folio, int reason)\n+\t\t\t\t\tstruct folio *new_folio, enum migrate_reason reason)\n {\n }\n \n@@ -956,7 +957,7 @@ static inline gfp_t htlb_modify_alloc_mask(struct hstate *h, gfp_t gfp_mask)\n \treturn modified_mask;\n }\n \n-static inline bool htlb_allow_alloc_fallback(int reason)\n+static inline bool htlb_allow_alloc_fallback(enum migrate_reason reason)\n {\n \tbool allowed_fallback = false;\n \n@@ -1238,7 +1239,7 @@ static inline gfp_t htlb_modify_alloc_mask(struct hstate *h, gfp_t gfp_mask)\n \treturn 0;\n }\n \n-static inline bool htlb_allow_alloc_fallback(int reason)\n+static inline bool htlb_allow_alloc_fallback(enum migrate_reason reason)\n {\n \treturn false;\n }\ndiff --git a/include/linux/migrate.h b/include/linux/migrate.h\nindex d5af2b7f577b33..1f83924615d6d3 100644\n--- a/include/linux/migrate.h\n+++ b/include/linux/migrate.h\n@@ -57,7 +57,8 @@ void putback_movable_pages(struct list_head *l);\n int migrate_folio(struct address_space *mapping, struct folio *dst,\n \t\tstruct folio *src, enum migrate_mode mode);\n int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free,\n-\t\t unsigned long private, enum migrate_mode mode, int reason,\n+\t\t unsigned long private, enum migrate_mode mode,\n+\t\t enum migrate_reason reason,\n \t\t unsigned int *ret_succeeded);\n struct folio *alloc_migration_target(struct folio *src, unsigned long private);\n bool isolate_movable_ops_page(struct page *page, isolate_mode_t mode);\n@@ -77,7 +78,8 @@ int set_movable_ops(const struct movable_operations *ops, enum pagetype type);\n static inline void putback_movable_pages(struct list_head *l) {}\n static inline int migrate_pages(struct list_head *l, new_folio_t new,\n \t\tfree_folio_t free, unsigned long private,\n-\t\tenum migrate_mode mode, int reason, unsigned int *ret_succeeded)\n+\t\tenum migrate_mode mode, enum migrate_reason reason,\n+\t\tunsigned int *ret_succeeded)\n \t{ return -ENOSYS; }\n static inline struct folio *alloc_migration_target(struct folio *src,\n \t\tunsigned long private)\ndiff --git a/include/linux/migrate_mode.h b/include/linux/migrate_mode.h\nindex 265c4328b36ad5..05102d4d2490e6 100644\n--- a/include/linux/migrate_mode.h\n+++ b/include/linux/migrate_mode.h\n@@ -25,6 +25,7 @@ enum migrate_reason {\n \tMR_LONGTERM_PIN,\n \tMR_DEMOTION,\n \tMR_DAMON,\n+\tMR_NEVER,\t\t/* page has never been migrated */\n \tMR_TYPES\n };\n \ndiff --git a/include/linux/page_owner.h b/include/linux/page_owner.h\nindex 3328357f6dba72..9fe51dfccf2685 100644\n--- a/include/linux/page_owner.h\n+++ b/include/linux/page_owner.h\n@@ -3,6 +3,7 @@\n #define __LINUX_PAGE_OWNER_H\n \n #include \u003clinux/jump_label.h\u003e\n+#include \u003clinux/migrate_mode.h\u003e\n \n #ifdef CONFIG_PAGE_OWNER\n extern struct static_key_false page_owner_inited;\n@@ -14,7 +15,7 @@ extern void __set_page_owner(struct page *page,\n extern void __split_page_owner(struct page *page, int old_order,\n \t\t\tint new_order);\n extern void __folio_copy_owner(struct folio *newfolio, struct folio *old);\n-extern void __folio_set_owner_migrate_reason(struct folio *folio, int reason);\n+extern void __folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason);\n extern void __dump_page_owner(const struct page *page);\n extern void pagetypeinfo_showmixedcount_print(struct seq_file *m,\n \t\t\t\t\tpg_data_t *pgdat, struct zone *zone);\n@@ -43,7 +44,7 @@ static inline void folio_copy_owner(struct folio *newfolio, struct folio *old)\n \tif (static_branch_unlikely(\u0026page_owner_inited))\n \t\t__folio_copy_owner(newfolio, old);\n }\n-static inline void folio_set_owner_migrate_reason(struct folio *folio, int reason)\n+static inline void folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason)\n {\n \tif (static_branch_unlikely(\u0026page_owner_inited))\n \t\t__folio_set_owner_migrate_reason(folio, reason);\n@@ -68,7 +69,7 @@ static inline void split_page_owner(struct page *page, int old_order,\n static inline void folio_copy_owner(struct folio *newfolio, struct folio *folio)\n {\n }\n-static inline void folio_set_owner_migrate_reason(struct folio *folio, int reason)\n+static inline void folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason)\n {\n }\n static inline void dump_page_owner(const struct page *page)\ndiff --git a/include/trace/events/migrate.h b/include/trace/events/migrate.h\nindex cd01dd7b3640dc..15ee2ef201b5f9 100644\n--- a/include/trace/events/migrate.h\n+++ b/include/trace/events/migrate.h\n@@ -23,7 +23,8 @@\n \tEM( MR_CONTIG_RANGE,\t\"contig_range\")\t\t\t\\\n \tEM( MR_LONGTERM_PIN,\t\"longterm_pin\")\t\t\t\\\n \tEM( MR_DEMOTION,\t\"demotion\")\t\t\t\\\n-\tEMe(MR_DAMON,\t\t\"damon\")\n+\tEM( MR_DAMON,\t\t\"damon\")\t\t\t\\\n+\tEMe(MR_NEVER,\t\t\"never_migrated\")\n \n /*\n * First define the enums in the above macros to be exported to userspace\n@@ -51,7 +52,7 @@ TRACE_EVENT(mm_migrate_pages,\n \tTP_PROTO(unsigned long succeeded, unsigned long failed,\n \t\t unsigned long thp_succeeded, unsigned long thp_failed,\n \t\t unsigned long thp_split, unsigned long large_folio_split,\n-\t\t enum migrate_mode mode, int reason),\n+\t\t enum migrate_mode mode, enum migrate_reason reason),\n \n \tTP_ARGS(succeeded, failed, thp_succeeded, thp_failed,\n \t\tthp_split, large_folio_split, mode, reason),\n@@ -64,7 +65,7 @@ TRACE_EVENT(mm_migrate_pages,\n \t\t__field(\tunsigned long,\t\tthp_split)\n \t\t__field(\tunsigned long,\t\tlarge_folio_split)\n \t\t__field(\tenum migrate_mode,\tmode)\n-\t\t__field(\tint,\t\t\treason)\n+\t\t__field(\tenum migrate_reason,\treason)\n \t),\n \n \tTP_fast_assign(\n@@ -91,13 +92,13 @@ TRACE_EVENT(mm_migrate_pages,\n \n TRACE_EVENT(mm_migrate_pages_start,\n \n-\tTP_PROTO(enum migrate_mode mode, int reason),\n+\tTP_PROTO(enum migrate_mode mode, enum migrate_reason reason),\n \n \tTP_ARGS(mode, reason),\n \n \tTP_STRUCT__entry(\n \t\t__field(enum migrate_mode, mode)\n-\t\t__field(int, reason)\n+\t\t__field(enum migrate_reason, reason)\n \t),\n \n \tTP_fast_assign(\ndiff --git a/mm/hugetlb.c b/mm/hugetlb.c\nindex 571212b80835ec..17732d1fdc5efd 100644\n--- a/mm/hugetlb.c\n+++ b/mm/hugetlb.c\n@@ -7182,7 +7182,8 @@ void folio_putback_hugetlb(struct folio *folio)\n \tfolio_put(folio);\n }\n \n-void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, int reason)\n+void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio,\n+\t\t\tenum migrate_reason reason)\n {\n \tstruct hstate *h = folio_hstate(old_folio);\n \ndiff --git a/mm/migrate.c b/mm/migrate.c\nindex d9b23909d716c6..49e10feeb094f0 100644\n--- a/mm/migrate.c\n+++ b/mm/migrate.c\n@@ -1469,7 +1469,7 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,\n static int unmap_and_move_huge_page(new_folio_t get_new_folio,\n \t\tfree_folio_t put_new_folio, unsigned long private,\n \t\tstruct folio *src, int force, enum migrate_mode mode,\n-\t\tint reason, struct list_head *ret)\n+\t\tenum migrate_reason reason, struct list_head *ret)\n {\n \tstruct folio *dst;\n \tint rc = -EAGAIN;\n@@ -1626,7 +1626,7 @@ struct migrate_pages_stats {\n */\n static int migrate_hugetlbs(struct list_head *from, new_folio_t get_new_folio,\n \t\t\t free_folio_t put_new_folio, unsigned long private,\n-\t\t\t enum migrate_mode mode, int reason,\n+\t\t\t enum migrate_mode mode, enum migrate_reason reason,\n \t\t\t struct migrate_pages_stats *stats,\n \t\t\t struct list_head *ret_folios)\n {\n@@ -1716,7 +1716,7 @@ static int migrate_hugetlbs(struct list_head *from, new_folio_t get_new_folio,\n static void migrate_folios_move(struct list_head *src_folios,\n \t\tstruct list_head *dst_folios,\n \t\tfree_folio_t put_new_folio, unsigned long private,\n-\t\tenum migrate_mode mode, int reason,\n+\t\tenum migrate_mode mode, enum migrate_reason reason,\n \t\tstruct list_head *ret_folios,\n \t\tstruct migrate_pages_stats *stats,\n \t\tint *retry, int *thp_retry, int *nr_failed,\n@@ -1799,7 +1799,7 @@ static void migrate_folios_undo(struct list_head *src_folios,\n */\n static int migrate_pages_batch(struct list_head *from,\n \t\tnew_folio_t get_new_folio, free_folio_t put_new_folio,\n-\t\tunsigned long private, enum migrate_mode mode, int reason,\n+\t\tunsigned long private, enum migrate_mode mode, enum migrate_reason reason,\n \t\tstruct list_head *ret_folios, struct list_head *split_folios,\n \t\tstruct migrate_pages_stats *stats, int nr_pass)\n {\n@@ -2011,7 +2011,7 @@ static int migrate_pages_batch(struct list_head *from,\n \n static int migrate_pages_sync(struct list_head *from, new_folio_t get_new_folio,\n \t\tfree_folio_t put_new_folio, unsigned long private,\n-\t\tenum migrate_mode mode, int reason,\n+\t\tenum migrate_mode mode, enum migrate_reason reason,\n \t\tstruct list_head *ret_folios, struct list_head *split_folios,\n \t\tstruct migrate_pages_stats *stats)\n {\n@@ -2088,7 +2088,7 @@ static int migrate_pages_sync(struct list_head *from, new_folio_t get_new_folio,\n */\n int migrate_pages(struct list_head *from, new_folio_t get_new_folio,\n \t\tfree_folio_t put_new_folio, unsigned long private,\n-\t\tenum migrate_mode mode, int reason, unsigned int *ret_succeeded)\n+\t\tenum migrate_mode mode, enum migrate_reason reason, unsigned int *ret_succeeded)\n {\n \tint rc, rc_gather;\n \tint nr_pages;\ndiff --git a/mm/page_owner.c b/mm/page_owner.c\nindex 2dddcb6510aa1e..46a933f9c229bd 100644\n--- a/mm/page_owner.c\n+++ b/mm/page_owner.c\n@@ -339,13 +339,13 @@ noinline void __set_page_owner(struct page *page, unsigned short order,\n \tdepot_stack_handle_t handle;\n \n \thandle = save_stack(gfp_mask);\n-\t__update_page_owner_handle(page, handle, order, gfp_mask, -1,\n+\t__update_page_owner_handle(page, handle, order, gfp_mask, MR_NEVER,\n \t\t\t\t ts_nsec, current-\u003epid, current-\u003etgid,\n \t\t\t\t current-\u003ecomm);\n \tinc_stack_record_count(handle, gfp_mask, 1 \u003c\u003c order);\n }\n \n-void __folio_set_owner_migrate_reason(struct folio *folio, int reason)\n+void __folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason)\n {\n \tstruct page_ext *page_ext = page_ext_get(\u0026folio-\u003epage);\n \tstruct page_owner *page_owner;\n@@ -422,6 +422,29 @@ void __folio_copy_owner(struct folio *newfolio, struct folio *old)\n \trcu_read_unlock();\n }\n \n+/*\n+ * Check if a page is a buddy page and advance @pfn past the entire buddy block.\n+ * This safely reads the buddy order without the zone lock, which may cause us\n+ * to skip less than the full buddy block, but that is acceptable for page owner\n+ * iteration purposes.\n+ *\n+ * Return: true if the page was skipped (caller should continue its loop),\n+ * false if the page is not a buddy page and should be processed normally.\n+ */\n+static inline bool skip_buddy_pages(unsigned long *pfn, struct page *page)\n+{\n+\tunsigned long order;\n+\n+\tif (!PageBuddy(page))\n+\t\treturn false;\n+\n+\torder = buddy_order_unsafe(page);\n+\tif (order \u003c= MAX_PAGE_ORDER)\n+\t\t*pfn += (1UL \u003c\u003c order) - 1;\n+\n+\treturn true;\n+}\n+\n void pagetypeinfo_showmixedcount_print(struct seq_file *m,\n \t\t\t\t pg_data_t *pgdat, struct zone *zone)\n {\n@@ -461,14 +484,8 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,\n \t\t\tif (page_zone(page) != zone)\n \t\t\t\tcontinue;\n \n-\t\t\tif (PageBuddy(page)) {\n-\t\t\t\tunsigned long freepage_order;\n-\n-\t\t\t\tfreepage_order = buddy_order_unsafe(page);\n-\t\t\t\tif (freepage_order \u003c= MAX_PAGE_ORDER)\n-\t\t\t\t\tpfn += (1UL \u003c\u003c freepage_order) - 1;\n+\t\t\tif (skip_buddy_pages(\u0026pfn, page))\n \t\t\t\tcontinue;\n-\t\t\t}\n \n \t\t\tif (PageReserved(page))\n \t\t\t\tcontinue;\n@@ -505,13 +522,13 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,\n \tseq_putc(m, '\\n');\n }\n \n+#ifdef CONFIG_MEMCG\n /*\n * Looking for memcg information and print it out\n */\n static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret,\n \t\t\t\t\t struct page *page)\n {\n-#ifdef CONFIG_MEMCG\n \tunsigned long memcg_data;\n \tstruct mem_cgroup *memcg;\n \tbool online;\n@@ -539,10 +556,16 @@ static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret,\n \t\t\tname);\n out_unlock:\n \trcu_read_unlock();\n-#endif /* CONFIG_MEMCG */\n \n \treturn ret;\n }\n+#else\n+static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret,\n+\t\t\t\t\t struct page *page)\n+{\n+\treturn ret;\n+}\n+#endif\n \n static ssize_t\n print_page_owner(char __user *buf, size_t count, unsigned long pfn,\n@@ -579,7 +602,7 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,\n \tif (ret \u003e= count)\n \t\tgoto err;\n \n-\tif (page_owner-\u003elast_migrate_reason != -1) {\n+\tif (page_owner-\u003elast_migrate_reason != MR_NEVER) {\n \t\tret += scnprintf(kbuf + ret, count - ret,\n \t\t\t\"Page has been migrated, last migrate reason: %s\\n\",\n \t\t\tmigrate_reason_names[page_owner-\u003elast_migrate_reason]);\n@@ -630,10 +653,10 @@ void __dump_page_owner(const struct page *page)\n \telse\n \t\tpr_alert(\"page_owner tracks the page as freed\\n\");\n \n-\tpr_alert(\"page last allocated via order %u, migratetype %s, gfp_mask %#x(%pGg), pid %d, tgid %d (%s), ts %llu, free_ts %llu\\n\",\n+\tpr_alert(\"page last allocated via order %u, migratetype %s, gfp_mask %#x(%pGg), pid %d, tgid %d (%s), ts %llu\\n\",\n \t\t page_owner-\u003eorder, migratetype_names[mt], gfp_mask, \u0026gfp_mask,\n \t\t page_owner-\u003epid, page_owner-\u003etgid, page_owner-\u003ecomm,\n-\t\t page_owner-\u003ets_nsec, page_owner-\u003efree_ts_nsec);\n+\t\t page_owner-\u003ets_nsec);\n \n \thandle = READ_ONCE(page_owner-\u003ehandle);\n \tif (!handle)\n@@ -645,12 +668,13 @@ void __dump_page_owner(const struct page *page)\n \tif (!handle) {\n \t\tpr_alert(\"page_owner free stack trace missing\\n\");\n \t} else {\n-\t\tpr_alert(\"page last free pid %d tgid %d stack trace:\\n\",\n-\t\t\t page_owner-\u003efree_pid, page_owner-\u003efree_tgid);\n+\t\tpr_alert(\"page last free pid %d tgid %d ts %llu stack trace:\\n\",\n+\t\t\t page_owner-\u003efree_pid, page_owner-\u003efree_tgid,\n+\t\t\t page_owner-\u003efree_ts_nsec);\n \t\tstack_depot_print(handle);\n \t}\n \n-\tif (page_owner-\u003elast_migrate_reason != -1)\n+\tif (page_owner-\u003elast_migrate_reason != MR_NEVER)\n \t\tpr_alert(\"page has been migrated, last migrate reason: %s\\n\",\n \t\t\tmigrate_reason_names[page_owner-\u003elast_migrate_reason]);\n \tpage_ext_put(page_ext);\n@@ -697,13 +721,8 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)\n \t\t}\n \n \t\tpage = pfn_to_page(pfn);\n-\t\tif (PageBuddy(page)) {\n-\t\t\tunsigned long freepage_order = buddy_order_unsafe(page);\n-\n-\t\t\tif (freepage_order \u003c= MAX_PAGE_ORDER)\n-\t\t\t\tpfn += (1UL \u003c\u003c freepage_order) - 1;\n+\t\tif (skip_buddy_pages(\u0026pfn, page))\n \t\t\tcontinue;\n-\t\t}\n \n \t\tpage_ext = page_ext_get(page);\n \t\tif (unlikely(!page_ext))\n@@ -798,20 +817,8 @@ static void init_pages_in_zone(struct zone *zone)\n \t\t\tif (page_zone(page) != zone)\n \t\t\t\tcontinue;\n \n-\t\t\t/*\n-\t\t\t * To avoid having to grab zone-\u003elock, be a little\n-\t\t\t * careful when reading buddy page order. The only\n-\t\t\t * danger is that we skip too much and potentially miss\n-\t\t\t * some early allocated pages, which is better than\n-\t\t\t * heavy lock contention.\n-\t\t\t */\n-\t\t\tif (PageBuddy(page)) {\n-\t\t\t\tunsigned long order = buddy_order_unsafe(page);\n-\n-\t\t\t\tif (order \u003e 0 \u0026\u0026 order \u003c= MAX_PAGE_ORDER)\n-\t\t\t\t\tpfn += (1UL \u003c\u003c order) - 1;\n+\t\t\tif (skip_buddy_pages(\u0026pfn, page))\n \t\t\t\tcontinue;\n-\t\t\t}\n \n \t\t\tif (PageReserved(page))\n \t\t\t\tcontinue;\n@@ -826,7 +833,7 @@ static void init_pages_in_zone(struct zone *zone)\n \n \t\t\t/* Found early allocated page */\n \t\t\t__update_page_owner_handle(page, early_handle, 0, 0,\n-\t\t\t\t\t\t -1, local_clock(), current-\u003epid,\n+\t\t\t\t\t\t MR_NEVER, local_clock(), current-\u003epid,\n \t\t\t\t\t\t current-\u003etgid, current-\u003ecomm);\n \t\t\tcount++;\n ext_put_continue:\n@@ -887,7 +894,7 @@ static void *stack_next(struct seq_file *m, void *v, loff_t *ppos)\n \treturn stack;\n }\n \n-static unsigned long page_owner_pages_threshold;\n+static unsigned long pages_threshold;\n \n static int stack_print(struct seq_file *m, void *v)\n {\n@@ -904,7 +911,7 @@ static int stack_print(struct seq_file *m, void *v)\n \tnr_base_pages = refcount_read(\u0026stack_record-\u003ecount) - 1;\n \n \tif (ctx-\u003eflags \u0026 STACK_PRINT_FLAG_PAGES \u0026\u0026\n-\t (nr_base_pages \u003c 1 || nr_base_pages \u003c page_owner_pages_threshold))\n+\t (nr_base_pages \u003c 1 || nr_base_pages \u003c pages_threshold))\n \t\treturn 0;\n \n \tif (ctx-\u003eflags \u0026 STACK_PRINT_FLAG_STACK) {\n@@ -926,16 +933,16 @@ static void stack_stop(struct seq_file *m, void *v)\n {\n }\n \n-static const struct seq_operations page_owner_stack_op = {\n+static const struct seq_operations stack_op = {\n \t.start\t= stack_start,\n \t.next\t= stack_next,\n \t.stop\t= stack_stop,\n \t.show\t= stack_print\n };\n \n-static int page_owner_stack_open(struct inode *inode, struct file *file)\n+static int stack_open(struct inode *inode, struct file *file)\n {\n-\tint ret = seq_open_private(file, \u0026page_owner_stack_op,\n+\tint ret = seq_open_private(file, \u0026stack_op,\n \t\t\t\t sizeof(struct stack_print_ctx));\n \n \tif (!ret) {\n@@ -948,28 +955,26 @@ static int page_owner_stack_open(struct inode *inode, struct file *file)\n \treturn ret;\n }\n \n-static const struct file_operations page_owner_stack_fops = {\n-\t.open\t\t= page_owner_stack_open,\n+static const struct file_operations stack_fops = {\n+\t.open\t\t= stack_open,\n \t.read\t\t= seq_read,\n \t.llseek\t\t= seq_lseek,\n \t.release\t= seq_release_private,\n };\n \n-static int page_owner_threshold_get(void *data, u64 *val)\n+static int threshold_get(void *data, u64 *val)\n {\n-\t*val = READ_ONCE(page_owner_pages_threshold);\n+\t*val = READ_ONCE(pages_threshold);\n \treturn 0;\n }\n \n-static int page_owner_threshold_set(void *data, u64 val)\n+static int threshold_set(void *data, u64 val)\n {\n-\tWRITE_ONCE(page_owner_pages_threshold, val);\n+\tWRITE_ONCE(pages_threshold, val);\n \treturn 0;\n }\n \n-DEFINE_SIMPLE_ATTRIBUTE(page_owner_threshold_fops, \u0026page_owner_threshold_get,\n-\t\t\t\u0026page_owner_threshold_set, \"%llu\");\n-\n+DEFINE_SIMPLE_ATTRIBUTE(threshold_fops, \u0026threshold_get, \u0026threshold_set, \"%llu\\n\");\n \n static int __init pageowner_init(void)\n {\n@@ -985,17 +990,17 @@ static int __init pageowner_init(void)\n \tdebugfs_create_file(\"show_stacks\", 0400, dir,\n \t\t\t (void *)(STACK_PRINT_FLAG_STACK |\n \t\t\t\t STACK_PRINT_FLAG_PAGES),\n-\t\t\t \u0026page_owner_stack_fops);\n+\t\t\t \u0026stack_fops);\n \tdebugfs_create_file(\"show_handles\", 0400, dir,\n \t\t\t (void *)(STACK_PRINT_FLAG_HANDLE |\n \t\t\t\t STACK_PRINT_FLAG_PAGES),\n-\t\t\t \u0026page_owner_stack_fops);\n+\t\t\t \u0026stack_fops);\n \tdebugfs_create_file(\"show_stacks_handles\", 0400, dir,\n \t\t\t (void *)(STACK_PRINT_FLAG_STACK |\n \t\t\t\t STACK_PRINT_FLAG_HANDLE),\n-\t\t\t \u0026page_owner_stack_fops);\n+\t\t\t \u0026stack_fops);\n \tdebugfs_create_file(\"count_threshold\", 0600, dir, NULL,\n-\t\t\t \u0026page_owner_threshold_fops);\n+\t\t\t \u0026threshold_fops);\n \treturn 0;\n }\n late_initcall(pageowner_init)\ndiff --git a/scripts/gdb/linux/page_owner.py b/scripts/gdb/linux/page_owner.py\nindex 8e713a09cfe78f..eeabaeed438b2a 100644\n--- a/scripts/gdb/linux/page_owner.py\n+++ b/scripts/gdb/linux/page_owner.py\n@@ -34,6 +34,7 @@ class DumpPageOwner(gdb.Command):\n max_pfn = None\n p_ops = None\n migrate_reason_names = None\n+ mr_never = None\n \n def __init__(self):\n super(DumpPageOwner, self).__init__(\"lx-dump-page-owner\", gdb.COMMAND_SUPPORT)\n@@ -65,6 +66,7 @@ class DumpPageOwner(gdb.Command):\n self.max_pfn = int(gdb.parse_and_eval(\"max_pfn\"))\n self.page_ext_size = int(gdb.parse_and_eval(\"page_ext_size\"))\n self.migrate_reason_names = gdb.parse_and_eval('migrate_reason_names')\n+ self.mr_never = int(gdb.parse_and_eval('MR_NEVER'))\n \n def page_ext_invalid(self, page_ext):\n if page_ext == gdb.Value(0):\n@@ -138,7 +140,7 @@ class DumpPageOwner(gdb.Command):\n else:\n gdb.write('page last free stack trace:\\n')\n stackdepot.stack_depot_print(page_owner[\"free_handle\"])\n- if page_owner['last_migrate_reason'] != -1:\n+ if page_owner['last_migrate_reason'] != self.mr_never:\n gdb.write('page has been migrated, last migrate reason: %s\\n' % self.migrate_reason_names[page_owner['last_migrate_reason']])\n \n def read_page_owner(self):\n"
} |
| 2/1 | 2026/07/01 07:16 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch consists of refactoring (changing 'int reason' to 'enum migrate_reason reason', extracting 'skip_buddy_pages', moving #ifdefs), tracepoint updates, and minor debugfs output formatting changes (adding a newline to a simple attribute). It does not functionally alter the execution flow of the kernel.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 6b07bb2671cd0ea0b90b40a4cc114b008d212e99
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Jul 1 07:16:32 2026 +0000
syz-cluster: applied patch under review
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 2abaf99321e90d..fa828232dfcc18 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 unpoison);
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)
}
static inline void move_hugetlb_state(struct folio *old_folio,
- struct folio *new_folio, int reason)
+ struct folio *new_folio, enum migrate_reason reason)
{
}
@@ -956,7 +957,7 @@ static inline gfp_t htlb_modify_alloc_mask(struct hstate *h, gfp_t gfp_mask)
return modified_mask;
}
-static inline bool htlb_allow_alloc_fallback(int reason)
+static inline bool htlb_allow_alloc_fallback(enum migrate_reason reason)
{
bool allowed_fallback = false;
@@ -1238,7 +1239,7 @@ static inline gfp_t htlb_modify_alloc_mask(struct hstate *h, gfp_t gfp_mask)
return 0;
}
-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 d5af2b7f577b33..1f83924615d6d3 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -57,7 +57,8 @@ 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 long private, enum migrate_mode mode,
+ enum migrate_reason reason,
unsigned int *ret_succeeded);
struct folio *alloc_migration_target(struct folio *src, unsigned long private);
bool isolate_movable_ops_page(struct page *page, isolate_mode_t mode);
@@ -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/migrate_mode.h b/include/linux/migrate_mode.h
index 265c4328b36ad5..05102d4d2490e6 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
};
diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h
index 3328357f6dba72..9fe51dfccf2685 100644
--- a/include/linux/page_owner.h
+++ b/include/linux/page_owner.h
@@ -3,6 +3,7 @@
#define __LINUX_PAGE_OWNER_H
#include <linux/jump_label.h>
+#include <linux/migrate_mode.h>
#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 reason);
+extern void __folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason 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 *newfolio, 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, enum 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, int 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, enum 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 cd01dd7b3640dc..15ee2ef201b5f9 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")
/*
* First define the enums in the above macros to be exported to userspace
@@ -51,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),
TP_ARGS(succeeded, failed, thp_succeeded, thp_failed,
thp_split, large_folio_split, mode, reason),
@@ -64,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)
),
TP_fast_assign(
@@ -91,13 +92,13 @@ TRACE_EVENT(mm_migrate_pages,
TRACE_EVENT(mm_migrate_pages_start,
- TP_PROTO(enum migrate_mode mode, int reason),
+ TP_PROTO(enum migrate_mode mode, enum migrate_reason reason),
TP_ARGS(mode, reason),
TP_STRUCT__entry(
__field(enum migrate_mode, mode)
- __field(int, reason)
+ __field(enum migrate_reason, reason)
),
TP_fast_assign(
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 571212b80835ec..17732d1fdc5efd 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -7182,7 +7182,8 @@ void folio_putback_hugetlb(struct folio *folio)
folio_put(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)
{
struct hstate *h = folio_hstate(old_folio);
diff --git a/mm/migrate.c b/mm/migrate.c
index d9b23909d716c6..49e10feeb094f0 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1469,7 +1469,7 @@ static int migrate_folio_move(free_folio_t put_new_folio, 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 = -EAGAIN;
@@ -1626,7 +1626,7 @@ struct migrate_pages_stats {
*/
static int migrate_hugetlbs(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 migrate_pages_stats *stats,
struct list_head *ret_folios)
{
@@ -1716,7 +1716,7 @@ static int migrate_hugetlbs(struct list_head *from, new_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 reason,
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,
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_succeeded)
{
int rc, rc_gather;
int nr_pages;
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 2dddcb6510aa1e..46a933f9c229bd 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -339,13 +339,13 @@ noinline void __set_page_owner(struct page *page, unsigned short order,
depot_stack_handle_t handle;
handle = 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);
}
-void __folio_set_owner_migrate_reason(struct folio *folio, int reason)
+void __folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason)
{
struct page_ext *page_ext = page_ext_get(&folio->page);
struct page_owner *page_owner;
@@ -422,6 +422,29 @@ void __folio_copy_owner(struct folio *newfolio, struct folio *old)
rcu_read_unlock();
}
+/*
+ * 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 cause 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 normally.
+ */
+static inline bool skip_buddy_pages(unsigned long *pfn, struct page *page)
+{
+ unsigned long order;
+
+ if (!PageBuddy(page))
+ return false;
+
+ order = buddy_order_unsafe(page);
+ if (order <= MAX_PAGE_ORDER)
+ *pfn += (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) != zone)
continue;
- if (PageBuddy(page)) {
- unsigned long freepage_order;
-
- freepage_order = buddy_order_unsafe(page);
- if (freepage_order <= MAX_PAGE_ORDER)
- pfn += (1UL << freepage_order) - 1;
+ if (skip_buddy_pages(&pfn, page))
continue;
- }
if (PageReserved(page))
continue;
@@ -505,13 +522,13 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,
seq_putc(m, '\n');
}
+#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;
@@ -539,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 */
return ret;
}
+#else
+static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret,
+ struct page *page)
+{
+ return ret;
+}
+#endif
static ssize_t
print_page_owner(char __user *buf, size_t count, unsigned long pfn,
@@ -579,7 +602,7 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
if (ret >= count)
goto err;
- if (page_owner->last_migrate_reason != -1) {
+ if (page_owner->last_migrate_reason != MR_NEVER) {
ret += scnprintf(kbuf + ret, count - ret,
"Page has been migrated, last migrate reason: %s\n",
migrate_reason_names[page_owner->last_migrate_reason]);
@@ -630,10 +653,10 @@ void __dump_page_owner(const struct page *page)
else
pr_alert("page_owner tracks the page as freed\n");
- 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);
handle = READ_ONCE(page_owner->handle);
if (!handle)
@@ -645,12 +668,13 @@ 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);
}
- if (page_owner->last_migrate_reason != -1)
+ if (page_owner->last_migrate_reason != 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);
@@ -697,13 +721,8 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
}
page = pfn_to_page(pfn);
- if (PageBuddy(page)) {
- unsigned long freepage_order = buddy_order_unsafe(page);
-
- if (freepage_order <= MAX_PAGE_ORDER)
- pfn += (1UL << freepage_order) - 1;
+ if (skip_buddy_pages(&pfn, page))
continue;
- }
page_ext = page_ext_get(page);
if (unlikely(!page_ext))
@@ -798,20 +817,8 @@ static void init_pages_in_zone(struct zone *zone)
if (page_zone(page) != zone)
continue;
- /*
- * 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 = buddy_order_unsafe(page);
-
- if (order > 0 && order <= MAX_PAGE_ORDER)
- pfn += (1UL << order) - 1;
+ if (skip_buddy_pages(&pfn, page))
continue;
- }
if (PageReserved(page))
continue;
@@ -826,7 +833,7 @@ static void init_pages_in_zone(struct zone *zone)
/* 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:
@@ -887,7 +894,7 @@ static void *stack_next(struct seq_file *m, void *v, loff_t *ppos)
return stack;
}
-static unsigned long page_owner_pages_threshold;
+static unsigned long pages_threshold;
static int stack_print(struct seq_file *m, void *v)
{
@@ -904,7 +911,7 @@ static int stack_print(struct seq_file *m, void *v)
nr_base_pages = refcount_read(&stack_record->count) - 1;
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;
if (ctx->flags & STACK_PRINT_FLAG_STACK) {
@@ -926,16 +933,16 @@ static void stack_stop(struct seq_file *m, void *v)
{
}
-static const struct seq_operations page_owner_stack_op = {
+static const struct seq_operations stack_op = {
.start = stack_start,
.next = stack_next,
.stop = stack_stop,
.show = stack_print
};
-static int page_owner_stack_open(struct inode *inode, struct file *file)
+static int stack_open(struct inode *inode, struct file *file)
{
- int ret = seq_open_private(file, &page_owner_stack_op,
+ int ret = seq_open_private(file, &stack_op,
sizeof(struct stack_print_ctx));
if (!ret) {
@@ -948,28 +955,26 @@ static int page_owner_stack_open(struct inode *inode, struct file *file)
return ret;
}
-static const struct file_operations page_owner_stack_fops = {
- .open = page_owner_stack_open,
+static const struct file_operations stack_fops = {
+ .open = stack_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_private,
};
-static int page_owner_threshold_get(void *data, u64 *val)
+static int threshold_get(void *data, u64 *val)
{
- *val = READ_ONCE(page_owner_pages_threshold);
+ *val = READ_ONCE(pages_threshold);
return 0;
}
-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;
}
-DEFINE_SIMPLE_ATTRIBUTE(page_owner_threshold_fops, &page_owner_threshold_get,
- &page_owner_threshold_set, "%llu");
-
+DEFINE_SIMPLE_ATTRIBUTE(threshold_fops, &threshold_get, &threshold_set, "%llu\n");
static int __init pageowner_init(void)
{
@@ -985,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)
diff --git a/scripts/gdb/linux/page_owner.py b/scripts/gdb/linux/page_owner.py
index 8e713a09cfe78f..eeabaeed438b2a 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 = None
p_ops = None
migrate_reason_names = None
+ mr_never = None
def __init__(self):
super(DumpPageOwner, self).__init__("lx-dump-page-owner", gdb.COMMAND_SUPPORT)
@@ -65,6 +66,7 @@ class DumpPageOwner(gdb.Command):
self.max_pfn = int(gdb.parse_and_eval("max_pfn"))
self.page_ext_size = int(gdb.parse_and_eval("page_ext_size"))
self.migrate_reason_names = gdb.parse_and_eval('migrate_reason_names')
+ self.mr_never = int(gdb.parse_and_eval('MR_NEVER'))
def page_ext_invalid(self, page_ext):
if page_ext == 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'] != -1:
+ if page_owner['last_migrate_reason'] != self.mr_never:
gdb.write('page has been migrated, last migrate reason: %s\n' % self.migrate_reason_names[page_owner['last_migrate_reason']])
def read_page_owner(self):
|
| 3/2 | 2026/07/01 07:16 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9316 output: 96 thoughts: 1327 Thoughts: **Fuzzing Analysis of a Page Migration Patch** Okay, so I've got this patch in front of me that tweaks several page migration and `page_owner` functions. My first thought is always: is there anything here that warrants fuzzing? Let's break it down. First, there's a type change: `int reason` is becoming `enum migrate_reason reason`. Also, `MR_NEVER` is being introduced, replacing `-1` in `page_owner.c`. This *feels* like a refactoring, but I need to be sure. It also touches `skip_buddy_pages`, some renaming in `page_owner.c`, adds `MR_NEVER` to a tracepoint, and updates a GDB script. Let's dive into the `skip_buddy_pages` refactoring. The old code had some conditional logic regarding buddy pages and orders. The new version simplifies it, calling the same function in several other places. I need to be *sure* this doesn't change behavior. Comparing the before and after, it looks like there's a difference where the new version checks `order <= MAX_PAGE_ORDER` where the old version checked `order > 0 && order <= MAX_PAGE_ORDER`. But if `order` is 0, the `pfn` isn't changed in either case, so this *isn't* a functional change. The other changes in this area are similar refactorings, just calling the new function in place of the old conditional checks, so still no functional change. Moving on, `print_page_owner_memcg` is now refactored with a move of the `#ifdef CONFIG_MEMCG` outside the function. Purely cosmetic, that's a no-go for fuzzing. Then there's the `threshold_fops` change: a `\n` added to the format string. This is a trivial change and a definite non-issue. I'm making sure I don't miss anything. The changes to `__update_page_owner_handle` and the comparison `page_owner->last_migrate_reason != MR_NEVER` are just consistency changes related to the introduction of `MR_NEVER`, another type-related change. Adding `MR_NEVER` to the `migrate_reason_names` array in the tracepoint header... again, refactoring, adding to a trace point's output, not a functional change. So, the overarching question: is there any new core kernel logic, or any drivers/architectures being touched that can be executed and fuzzed? Nope. It's mostly refactoring, some type updates, and minor changes to how the `page_owner` debug feature works. The `page_owner` is really a debugging aid, not a core path, so I can confidently say this patch doesn't add any new attack surface or introduce any new bugs that need to be tested for. The patch really only makes changes that are: modifications to numeric constants, purely decorative changes and refactoring. Based on this analysis and my understanding of the fuzzing rules, I'm setting `WorthFuzzing=false`. |
| 4/2 | 2026/07/01 07:16 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch consists of refactoring (changing 'int reason' to 'enum migrate_reason reason', extracting 'skip_buddy_pages', moving #ifdefs), tracepoint updates, and minor debugfs output formatting changes (adding a newline to a simple attribute). It does not functionally alter the execution flow of the kernel.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch consists of refactoring (changing 'int reason' to 'enum migrate_reason reason', extracting 'skip_buddy_pages', moving #ifdefs), tracepoint updates, and minor debugfs output formatting changes (adding a newline to a simple attribute). It does not functionally alter the execution flow of the kernel.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|