page_mapped_in_vma() really just wants to walk one page, but as the code stands, if passed the head page of a compound page, it will walk every page in the compound page. Extract pfn/nr_pages/pgoff from the struct page early, so they can be overridden by page_mapped_in_vma().
Showing the changes to include (2 of 6 files). Show all
Unified · Split
| @@ -970,6 +970,11 @@ static inline struct hstate *page_hstate(struct page *page) · 969 unmodified lines | ||
| 970 | 970 | return NULL; |
| 971 | 971 | } |
| 972 | 972 | |
| 973 | +static inline struct hstate *size_to_hstate(unsigned long size) | |
| 974 | +{ | |
| 975 | + return NULL; | |
| 976 | +} | |
| 977 | + | |
| 973 | 978 | static inline unsigned long huge_page_size(struct hstate *h) |
| 974 | 979 | { |
| 975 | 980 | return PAGE_SIZE; |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/rwsem.h> |
| 12 | 12 | #include <linux/memcontrol.h> |
| 13 | 13 | #include <linux/highmem.h> |
| 14 | +#include <linux/pagemap.h> | |
| 14 | 15 | |
| 15 | 16 | /* |
| 16 | 17 | * The anon_vma heads a list of private "related" vmas, to scan if |
| @@ -201,11 +202,13 @@ int make_device_exclusive_range(struct mm_struct *mm, unsigned long start, · 184 unmodified lines | ||
| 201 | 202 | |
| 202 | 203 | /* Avoid racy checks */ |
| 203 | 204 | #define PVMW_SYNC (1 << 0) |
| 204 | −/* Look for migarion entries rather than present PTEs */ | |
| 205 | +/* Look for migration entries rather than present PTEs */ | |
| 205 | 206 | #define PVMW_MIGRATION (1 << 1) |
| 206 | 207 | |
| 207 | 208 | struct page_vma_mapped_walk { |
| 208 | − struct page *page; | |
| 209 | + unsigned long pfn; | |
| 210 | + unsigned long nr_pages; | |
| 211 | + pgoff_t pgoff; | |
| 209 | 212 | struct vm_area_struct *vma; |
| 210 | 213 | unsigned long address; |
| 211 | 214 | pmd_t *pmd; |
| @@ -216,7 +219,9 @@ struct page_vma_mapped_walk { · 4 unmodified lines | ||
| 216 | 219 | |
| 217 | 220 | #define DEFINE_PAGE_VMA_WALK(name, _page, _vma, _address, _flags) \ |
| 218 | 221 | struct page_vma_mapped_walk name = { \ |
| 219 | − .page = _page, \ | |
| 222 | + .pfn = page_to_pfn(_page), \ | |
| 223 | + .nr_pages = compound_nr(page), \ | |
| 224 | + .pgoff = page_to_pgoff(page), \ | |
| 220 | 225 | .vma = _vma, \ |
| 221 | 226 | .address = _address, \ |
| 222 | 227 | .flags = _flags, \ |
| @@ -224,7 +229,9 @@ struct page_vma_mapped_walk { · 1 unmodified line | ||
| 224 | 229 | |
| 225 | 230 | #define DEFINE_FOLIO_VMA_WALK(name, _folio, _vma, _address, _flags) \ |
| 226 | 231 | struct page_vma_mapped_walk name = { \ |
| 227 | − .page = &_folio->page, \ | |
| 232 | + .pfn = folio_pfn(_folio), \ | |
| 233 | + .nr_pages = folio_nr_pages(_folio), \ | |
| 234 | + .pgoff = folio_pgoff(_folio), \ | |
| 228 | 235 | .vma = _vma, \ |
| 229 | 236 | .address = _address, \ |
| 230 | 237 | .flags = _flags, \ |
| @@ -233,7 +240,7 @@ struct page_vma_mapped_walk { · 2 unmodified lines | ||
| 233 | 240 | static inline void page_vma_mapped_walk_done(struct page_vma_mapped_walk *pvmw) |
| 234 | 241 | { |
| 235 | 242 | /* HugeTLB pte is set to the relevant page table entry without pte_mapped. */ |
| 236 | − if (pvmw->pte && !PageHuge(pvmw->page)) | |
| 243 | + if (pvmw->pte && !is_vm_hugetlb_page(pvmw->vma)) | |
| 237 | 244 | pte_unmap(pvmw->pte); |
| 238 | 245 | if (pvmw->ptl) |
| 239 | 246 | spin_unlock(pvmw->ptl); |