@@ -2200,16 +2200,6 @@ unsigned filemap_get_folios(struct address_space *mapping, pgoff_t *start,
22002200}
22012201EXPORT_SYMBOL (filemap_get_folios );
22022202
2203- static inline
2204- bool folio_more_pages (struct folio * folio , pgoff_t index , pgoff_t max )
2205- {
2206- if (!folio_test_large (folio ) || folio_test_hugetlb (folio ))
2207- return false;
2208- if (index >= max )
2209- return false;
2210- return index < folio -> index + folio_nr_pages (folio ) - 1 ;
2211- }
2212-
22132203/**
22142204 * filemap_get_folios_contig - Get a batch of contiguous folios
22152205 * @mapping: The address_space to search
@@ -3351,6 +3341,53 @@ static inline struct folio *next_map_page(struct address_space *mapping,
33513341 mapping , xas , end_pgoff );
33523342}
33533343
3344+ /*
3345+ * Map page range [start_page, start_page + nr_pages) of folio.
3346+ * start_page is gotten from start by folio_page(folio, start)
3347+ */
3348+ static vm_fault_t filemap_map_folio_range (struct vm_fault * vmf ,
3349+ struct folio * folio , unsigned long start ,
3350+ unsigned long addr , unsigned int nr_pages )
3351+ {
3352+ vm_fault_t ret = 0 ;
3353+ struct vm_area_struct * vma = vmf -> vma ;
3354+ struct file * file = vma -> vm_file ;
3355+ struct page * page = folio_page (folio , start );
3356+ unsigned int mmap_miss = READ_ONCE (file -> f_ra .mmap_miss );
3357+ unsigned int ref_count = 0 , count = 0 ;
3358+
3359+ do {
3360+ if (PageHWPoison (page ))
3361+ continue ;
3362+
3363+ if (mmap_miss > 0 )
3364+ mmap_miss -- ;
3365+
3366+ /*
3367+ * NOTE: If there're PTE markers, we'll leave them to be
3368+ * handled in the specific fault path, and it'll prohibit the
3369+ * fault-around logic.
3370+ */
3371+ if (!pte_none (* vmf -> pte ))
3372+ continue ;
3373+
3374+ if (vmf -> address == addr )
3375+ ret = VM_FAULT_NOPAGE ;
3376+
3377+ ref_count ++ ;
3378+ do_set_pte (vmf , page , addr );
3379+ update_mmu_cache (vma , addr , vmf -> pte );
3380+ } while (vmf -> pte ++ , page ++ , addr += PAGE_SIZE , ++ count < nr_pages );
3381+
3382+ /* Restore the vmf->pte */
3383+ vmf -> pte -= nr_pages ;
3384+
3385+ folio_ref_add (folio , ref_count );
3386+ WRITE_ONCE (file -> f_ra .mmap_miss , mmap_miss );
3387+
3388+ return ret ;
3389+ }
3390+
33543391vm_fault_t filemap_map_pages (struct vm_fault * vmf ,
33553392 pgoff_t start_pgoff , pgoff_t end_pgoff )
33563393{
@@ -3361,9 +3398,9 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf,
33613398 unsigned long addr ;
33623399 XA_STATE (xas , & mapping -> i_pages , start_pgoff );
33633400 struct folio * folio ;
3364- struct page * page ;
33653401 unsigned int mmap_miss = READ_ONCE (file -> f_ra .mmap_miss );
33663402 vm_fault_t ret = 0 ;
3403+ int nr_pages = 0 ;
33673404
33683405 rcu_read_lock ();
33693406 folio = first_map_page (mapping , & xas , end_pgoff );
@@ -3378,45 +3415,18 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf,
33783415 addr = vma -> vm_start + ((start_pgoff - vma -> vm_pgoff ) << PAGE_SHIFT );
33793416 vmf -> pte = pte_offset_map_lock (vma -> vm_mm , vmf -> pmd , addr , & vmf -> ptl );
33803417 do {
3381- again :
3382- page = folio_file_page (folio , xas .xa_index );
3383- if (PageHWPoison (page ))
3384- goto unlock ;
3385-
3386- if (mmap_miss > 0 )
3387- mmap_miss -- ;
3418+ unsigned long end ;
33883419
33893420 addr += (xas .xa_index - last_pgoff ) << PAGE_SHIFT ;
33903421 vmf -> pte += xas .xa_index - last_pgoff ;
33913422 last_pgoff = xas .xa_index ;
3423+ end = folio -> index + folio_nr_pages (folio ) - 1 ;
3424+ nr_pages = min (end , end_pgoff ) - xas .xa_index + 1 ;
33923425
3393- /*
3394- * NOTE: If there're PTE markers, we'll leave them to be
3395- * handled in the specific fault path, and it'll prohibit the
3396- * fault-around logic.
3397- */
3398- if (!pte_none (* vmf -> pte ))
3399- goto unlock ;
3400-
3401- /* We're about to handle the fault */
3402- if (vmf -> address == addr )
3403- ret = VM_FAULT_NOPAGE ;
3426+ ret |= filemap_map_folio_range (vmf , folio ,
3427+ xas .xa_index - folio -> index , addr , nr_pages );
3428+ xas .xa_index += nr_pages ;
34043429
3405- do_set_pte (vmf , page , addr );
3406- /* no need to invalidate: a not-present page won't be cached */
3407- update_mmu_cache (vma , addr , vmf -> pte );
3408- if (folio_more_pages (folio , xas .xa_index , end_pgoff )) {
3409- xas .xa_index ++ ;
3410- folio_ref_inc (folio );
3411- goto again ;
3412- }
3413- folio_unlock (folio );
3414- continue ;
3415- unlock :
3416- if (folio_more_pages (folio , xas .xa_index , end_pgoff )) {
3417- xas .xa_index ++ ;
3418- goto again ;
3419- }
34203430 folio_unlock (folio );
34213431 folio_put (folio );
34223432 } while ((folio = next_map_page (mapping , & xas , end_pgoff )) != NULL );
0 commit comments