If the VMA is a CoW mapping page offset may differ from anon page offset,
indicating different positions in the relevant rmap trees.

Update print_bad_page_map() to reflect that - if the mapping is non-CoW or
the indexes match, then output only one index as before, otherwise output
both with (file) or (anon) suffixes to reflect which is which.

It's not possible to give only one index as there is no folio available to
perform folio_test_anon() upon (the page table entry is bad so this is
unavailable).

This is potentially useful debugging information and matches the existing
page offset provided.

Use the raw __linear_anon_page_index() function so as to always output this
value regardless of whether the mapping is file-backed or not and to avoid
asserts that shouldn't apply here.

Acked-by: David Hildenbrand (Arm) <[email protected]>
Reviewed-by: Gregory Price (Meta) <[email protected]>
Signed-off-by: Lorenzo Stoakes (ARM) <[email protected]>
---
 mm/memory.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index e1349e18f046..3bd3616b27d2 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -631,13 +631,14 @@ static void print_bad_page_map(struct vm_area_struct *vma,
 {
        struct address_space *mapping;
        char entry_str[PTVAL_STR_MAX];
-       pgoff_t index;
+       pgoff_t index, anon_index;
 
        if (is_bad_page_map_ratelimited())
                return;
 
        mapping = vma->vm_file ? vma->vm_file->f_mapping : NULL;
        index = linear_page_index(vma, addr);
+       anon_index = __linear_anon_page_index(vma, addr);
 
        ptval_bytes_to_hex_str(entry_str, sizeof(entry_str), entry, entry_size);
        pr_alert("BUG: Bad page map in process %s  %s:%s", current->comm,
@@ -645,8 +646,14 @@ static void print_bad_page_map(struct vm_area_struct *vma,
        __print_bad_page_map_pgtable(vma->vm_mm, addr);
        if (page)
                dump_page(page, "bad page map");
-       pr_alert("addr:%px vm_flags:%08lx anon_vma:%px mapping:%px index:%lx\n",
-                (void *)addr, vma->vm_flags, vma->anon_vma, mapping, index);
+       pr_alert("addr:%px vm_flags:%08lx anon_vma:%px mapping:%px",
+                (void *)addr, vma->vm_flags, vma->anon_vma, mapping);
+       if (!vma_is_cow_mapping(vma) || index == anon_index) {
+               pr_cont(" index:%lx\n", index);
+       } else {
+               pr_cont(" index:%lx (file) %lx (anon)\n", index, anon_index);
+       }
+
        pr_alert("file:%pD fault:%ps mmap:%ps mmap_prepare: %ps 
read_folio:%ps\n",
                 vma->vm_file,
                 vma->vm_ops ? vma->vm_ops->fault : NULL,

-- 
2.55.0


Reply via email to