|
|
@@ -183,6 +183,31 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
+void __dump_page_owner(struct page *page)
|
|
|
+{
|
|
|
+ struct page_ext *page_ext = lookup_page_ext(page);
|
|
|
+ struct stack_trace trace = {
|
|
|
+ .nr_entries = page_ext->nr_entries,
|
|
|
+ .entries = &page_ext->trace_entries[0],
|
|
|
+ };
|
|
|
+ gfp_t gfp_mask = page_ext->gfp_mask;
|
|
|
+ int mt = gfpflags_to_migratetype(gfp_mask);
|
|
|
+
|
|
|
+ if (!test_bit(PAGE_EXT_OWNER, &page_ext->flags)) {
|
|
|
+ pr_alert("page_owner info is not active (free page?)\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ pr_alert("page allocated via order %u, migratetype %s, "
|
|
|
+ "gfp_mask %#x(%pGg)\n", page_ext->order,
|
|
|
+ migratetype_names[mt], gfp_mask, &gfp_mask);
|
|
|
+ print_stack_trace(&trace, 0);
|
|
|
+
|
|
|
+ if (page_ext->last_migrate_reason != -1)
|
|
|
+ pr_alert("page has been migrated, last migrate reason: %s\n",
|
|
|
+ migrate_reason_names[page_ext->last_migrate_reason]);
|
|
|
+}
|
|
|
+
|
|
|
static ssize_t
|
|
|
read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|
|
{
|