Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hugetlb: convert hugetlb_no_page() to use struct vm_fault

hugetlb_no_page() can use the struct vm_fault passed in from
hugetlb_fault(). This alleviates the stack by consolidating 7
variables into a single struct.

[vishal.moola@gmail.com: simplify hugetlb_no_page() arguments]
Link: https://lkml.kernel.org/r/ZhQtN8y5zud8iI1u@fedora
Link: https://lkml.kernel.org/r/20240401202651.31440-3-vishal.moola@gmail.com
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Reviewed-by: Oscar Salvador <osalvador@suse.de>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Muchun Song <muchun.song@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Vishal Moola (Oracle) and committed by
Andrew Morton
7b6ec181 9b42fa16

+31 -32
+31 -32
mm/hugetlb.c
··· 6188 6188 return same; 6189 6189 } 6190 6190 6191 - static vm_fault_t hugetlb_no_page(struct mm_struct *mm, 6192 - struct vm_area_struct *vma, 6193 - struct address_space *mapping, pgoff_t idx, 6194 - unsigned long address, pte_t *ptep, 6195 - pte_t old_pte, unsigned int flags, 6191 + static vm_fault_t hugetlb_no_page(struct address_space *mapping, 6196 6192 struct vm_fault *vmf) 6197 6193 { 6194 + struct vm_area_struct *vma = vmf->vma; 6195 + struct mm_struct *mm = vma->vm_mm; 6198 6196 struct hstate *h = hstate_vma(vma); 6199 6197 vm_fault_t ret = VM_FAULT_SIGBUS; 6200 6198 int anon_rmap = 0; 6201 6199 unsigned long size; 6202 6200 struct folio *folio; 6203 6201 pte_t new_pte; 6204 - spinlock_t *ptl; 6205 - unsigned long haddr = address & huge_page_mask(h); 6206 6202 bool new_folio, new_pagecache_folio = false; 6207 - u32 hash = hugetlb_fault_mutex_hash(mapping, idx); 6203 + u32 hash = hugetlb_fault_mutex_hash(mapping, vmf->pgoff); 6208 6204 6209 6205 /* 6210 6206 * Currently, we are forced to kill the process in the event the ··· 6219 6223 * before we get page_table_lock. 6220 6224 */ 6221 6225 new_folio = false; 6222 - folio = filemap_lock_hugetlb_folio(h, mapping, idx); 6226 + folio = filemap_lock_hugetlb_folio(h, mapping, vmf->pgoff); 6223 6227 if (IS_ERR(folio)) { 6224 6228 size = i_size_read(mapping->host) >> huge_page_shift(h); 6225 - if (idx >= size) 6229 + if (vmf->pgoff >= size) 6226 6230 goto out; 6227 6231 /* Check for page in userfault range */ 6228 6232 if (userfaultfd_missing(vma)) { ··· 6243 6247 * never happen on the page after UFFDIO_COPY has 6244 6248 * correctly installed the page and returned. 6245 6249 */ 6246 - if (!hugetlb_pte_stable(h, mm, ptep, old_pte)) { 6250 + if (!hugetlb_pte_stable(h, mm, vmf->pte, vmf->orig_pte)) { 6247 6251 ret = 0; 6248 6252 goto out; 6249 6253 } ··· 6258 6262 goto out; 6259 6263 } 6260 6264 6261 - folio = alloc_hugetlb_folio(vma, haddr, 0); 6265 + folio = alloc_hugetlb_folio(vma, vmf->address, 0); 6262 6266 if (IS_ERR(folio)) { 6263 6267 /* 6264 6268 * Returning error will result in faulting task being ··· 6272 6276 * here. Before returning error, get ptl and make 6273 6277 * sure there really is no pte entry. 6274 6278 */ 6275 - if (hugetlb_pte_stable(h, mm, ptep, old_pte)) 6279 + if (hugetlb_pte_stable(h, mm, vmf->pte, vmf->orig_pte)) 6276 6280 ret = vmf_error(PTR_ERR(folio)); 6277 6281 else 6278 6282 ret = 0; 6279 6283 goto out; 6280 6284 } 6281 - clear_huge_page(&folio->page, address, pages_per_huge_page(h)); 6285 + clear_huge_page(&folio->page, vmf->real_address, 6286 + pages_per_huge_page(h)); 6282 6287 __folio_mark_uptodate(folio); 6283 6288 new_folio = true; 6284 6289 6285 6290 if (vma->vm_flags & VM_MAYSHARE) { 6286 - int err = hugetlb_add_to_page_cache(folio, mapping, idx); 6291 + int err = hugetlb_add_to_page_cache(folio, mapping, 6292 + vmf->pgoff); 6287 6293 if (err) { 6288 6294 /* 6289 6295 * err can't be -EEXIST which implies someone ··· 6294 6296 * to the page cache. So it's safe to call 6295 6297 * restore_reserve_on_error() here. 6296 6298 */ 6297 - restore_reserve_on_error(h, vma, haddr, folio); 6299 + restore_reserve_on_error(h, vma, vmf->address, 6300 + folio); 6298 6301 folio_put(folio); 6299 6302 ret = VM_FAULT_SIGBUS; 6300 6303 goto out; ··· 6322 6323 folio_unlock(folio); 6323 6324 folio_put(folio); 6324 6325 /* See comment in userfaultfd_missing() block above */ 6325 - if (!hugetlb_pte_stable(h, mm, ptep, old_pte)) { 6326 + if (!hugetlb_pte_stable(h, mm, vmf->pte, vmf->orig_pte)) { 6326 6327 ret = 0; 6327 6328 goto out; 6328 6329 } ··· 6337 6338 * any allocations necessary to record that reservation occur outside 6338 6339 * the spinlock. 6339 6340 */ 6340 - if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) { 6341 - if (vma_needs_reservation(h, vma, haddr) < 0) { 6341 + if ((vmf->flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) { 6342 + if (vma_needs_reservation(h, vma, vmf->address) < 0) { 6342 6343 ret = VM_FAULT_OOM; 6343 6344 goto backout_unlocked; 6344 6345 } 6345 6346 /* Just decrements count, does not deallocate */ 6346 - vma_end_reservation(h, vma, haddr); 6347 + vma_end_reservation(h, vma, vmf->address); 6347 6348 } 6348 6349 6349 - ptl = huge_pte_lock(h, mm, ptep); 6350 + vmf->ptl = huge_pte_lock(h, mm, vmf->pte); 6350 6351 ret = 0; 6351 6352 /* If pte changed from under us, retry */ 6352 - if (!pte_same(huge_ptep_get(ptep), old_pte)) 6353 + if (!pte_same(huge_ptep_get(vmf->pte), vmf->orig_pte)) 6353 6354 goto backout; 6354 6355 6355 6356 if (anon_rmap) 6356 - hugetlb_add_new_anon_rmap(folio, vma, haddr); 6357 + hugetlb_add_new_anon_rmap(folio, vma, vmf->address); 6357 6358 else 6358 6359 hugetlb_add_file_rmap(folio); 6359 6360 new_pte = make_huge_pte(vma, &folio->page, ((vma->vm_flags & VM_WRITE) ··· 6362 6363 * If this pte was previously wr-protected, keep it wr-protected even 6363 6364 * if populated. 6364 6365 */ 6365 - if (unlikely(pte_marker_uffd_wp(old_pte))) 6366 + if (unlikely(pte_marker_uffd_wp(vmf->orig_pte))) 6366 6367 new_pte = huge_pte_mkuffd_wp(new_pte); 6367 - set_huge_pte_at(mm, haddr, ptep, new_pte, huge_page_size(h)); 6368 + set_huge_pte_at(mm, vmf->address, vmf->pte, new_pte, huge_page_size(h)); 6368 6369 6369 6370 hugetlb_count_add(pages_per_huge_page(h), mm); 6370 - if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) { 6371 + if ((vmf->flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) { 6371 6372 /* Optimization, do the COW without a second fault */ 6372 - ret = hugetlb_wp(mm, vma, address, ptep, flags, folio, ptl, vmf); 6373 + ret = hugetlb_wp(mm, vma, vmf->real_address, vmf->pte, 6374 + vmf->flags, folio, vmf->ptl, vmf); 6373 6375 } 6374 6376 6375 - spin_unlock(ptl); 6377 + spin_unlock(vmf->ptl); 6376 6378 6377 6379 /* 6378 6380 * Only set hugetlb_migratable in newly allocated pages. Existing pages ··· 6390 6390 return ret; 6391 6391 6392 6392 backout: 6393 - spin_unlock(ptl); 6393 + spin_unlock(vmf->ptl); 6394 6394 backout_unlocked: 6395 6395 if (new_folio && !new_pagecache_folio) 6396 - restore_reserve_on_error(h, vma, haddr, folio); 6396 + restore_reserve_on_error(h, vma, vmf->address, folio); 6397 6397 6398 6398 folio_unlock(folio); 6399 6399 folio_put(folio); ··· 6489 6489 * hugetlb_no_page will drop vma lock and hugetlb fault 6490 6490 * mutex internally, which make us return immediately. 6491 6491 */ 6492 - return hugetlb_no_page(mm, vma, mapping, vmf.pgoff, address, 6493 - vmf.pte, vmf.orig_pte, flags, &vmf); 6492 + return hugetlb_no_page(mapping, &vmf); 6494 6493 } 6495 6494 6496 6495 ret = 0;