The VM_BUG_ON_PAGE in page_move_anon_rmap() is more trouble than it's worth: the syzkaller fuzzer hit it again. It's still wrong for some THP cases, because linear_page_index() was never intended to apply to addresses before the start of a vma. That's easily fixed with a signed long cast inside linear_page_index(); and Dmitry has tested such a patch, to verify the false positive. But why extend linear_page_index() just for this case? when the avoidance in page_move_anon_rmap() has already grown ugly, and there's no reason for the check at all (nothing else there is using address or index). Remove address arg from page_move_anon_rmap(), remove VM_BUG_ON_PAGE, remove CONFIG_DEBUG_VM PageTransHuge adjustment. And one more thing: should the compound_head(page) be done inside or outside page_move_anon_rmap()? It's usually pushed down to the lowest level nowadays (and mm/memory.c shows no other explicit use of it), so I think it's better done in page_move_anon_rmap() than by caller.
Showing the changes to include (1 of 4 files). Show all
Unified · Split
| @@ -158,7 +158,7 @@ struct anon_vma *page_get_anon_vma(struct page *page); · 157 unmodified lines | ||
| 158 | 158 | /* |
| 159 | 159 | * rmap interfaces called when adding or removing pte of page |
| 160 | 160 | */ |
| 161 | −void page_move_anon_rmap(struct page *, struct vm_area_struct *, unsigned long); | |
| 161 | +void page_move_anon_rmap(struct page *, struct vm_area_struct *); | |
| 162 | 162 | void page_add_anon_rmap(struct page *, struct vm_area_struct *, |
| 163 | 163 | unsigned long, bool); |
| 164 | 164 | void do_page_add_anon_rmap(struct page *, struct vm_area_struct *, |