@@ -411,18 +411,71 @@ hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end,
411
411
}
412
412
}
413
413
414
+ /*
415
+ * Called with hugetlb fault mutex held.
416
+ * Returns true if page was actually removed, false otherwise.
417
+ */
418
+ static bool remove_inode_single_folio (struct hstate * h , struct inode * inode ,
419
+ struct address_space * mapping ,
420
+ struct folio * folio , pgoff_t index ,
421
+ bool truncate_op )
422
+ {
423
+ bool ret = false;
424
+
425
+ /*
426
+ * If folio is mapped, it was faulted in after being
427
+ * unmapped in caller. Unmap (again) while holding
428
+ * the fault mutex. The mutex will prevent faults
429
+ * until we finish removing the folio.
430
+ */
431
+ if (unlikely (folio_mapped (folio ))) {
432
+ i_mmap_lock_write (mapping );
433
+ hugetlb_vmdelete_list (& mapping -> i_mmap ,
434
+ index * pages_per_huge_page (h ),
435
+ (index + 1 ) * pages_per_huge_page (h ),
436
+ ZAP_FLAG_DROP_MARKER );
437
+ i_mmap_unlock_write (mapping );
438
+ }
439
+
440
+ folio_lock (folio );
441
+ /*
442
+ * After locking page, make sure mapping is the same.
443
+ * We could have raced with page fault populate and
444
+ * backout code.
445
+ */
446
+ if (folio_mapping (folio ) == mapping ) {
447
+ /*
448
+ * We must remove the folio from page cache before removing
449
+ * the region/ reserve map (hugetlb_unreserve_pages). In
450
+ * rare out of memory conditions, removal of the region/reserve
451
+ * map could fail. Correspondingly, the subpool and global
452
+ * reserve usage count can need to be adjusted.
453
+ */
454
+ VM_BUG_ON (HPageRestoreReserve (& folio -> page ));
455
+ hugetlb_delete_from_page_cache (& folio -> page );
456
+ ret = true;
457
+ if (!truncate_op ) {
458
+ if (unlikely (hugetlb_unreserve_pages (inode , index ,
459
+ index + 1 , 1 )))
460
+ hugetlb_fix_reserve_counts (inode );
461
+ }
462
+ }
463
+
464
+ folio_unlock (folio );
465
+ return ret ;
466
+ }
467
+
414
468
/*
415
469
* remove_inode_hugepages handles two distinct cases: truncation and hole
416
470
* punch. There are subtle differences in operation for each case.
417
471
*
418
472
* truncation is indicated by end of range being LLONG_MAX
419
473
* In this case, we first scan the range and release found pages.
420
474
* After releasing pages, hugetlb_unreserve_pages cleans up region/reserve
421
- * maps and global counts. Page faults can not race with truncation
422
- * in this routine. hugetlb_no_page() prevents page faults in the
423
- * truncated range. It checks i_size before allocation, and again after
424
- * with the page table lock for the page held. The same lock must be
425
- * acquired to unmap a page.
475
+ * maps and global counts. Page faults can race with truncation.
476
+ * During faults, hugetlb_no_page() checks i_size before page allocation,
477
+ * and again after obtaining page table lock. It will 'back out'
478
+ * allocations in the truncated range.
426
479
* hole punch is indicated if end is not LLONG_MAX
427
480
* In the hole punch case we scan the range and release found pages.
428
481
* Only when releasing a page is the associated region/reserve map
@@ -456,44 +509,12 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
456
509
mutex_lock (& hugetlb_fault_mutex_table [hash ]);
457
510
458
511
/*
459
- * If folio is mapped, it was faulted in after being
460
- * unmapped in caller. Unmap (again) now after taking
461
- * the fault mutex. The mutex will prevent faults
462
- * until we finish removing the folio.
463
- *
464
- * This race can only happen in the hole punch case.
465
- * Getting here in a truncate operation is a bug.
512
+ * Remove folio that was part of folio_batch.
466
513
*/
467
- if (unlikely (folio_mapped (folio ))) {
468
- BUG_ON (truncate_op );
469
-
470
- i_mmap_lock_write (mapping );
471
- hugetlb_vmdelete_list (& mapping -> i_mmap ,
472
- index * pages_per_huge_page (h ),
473
- (index + 1 ) * pages_per_huge_page (h ),
474
- ZAP_FLAG_DROP_MARKER );
475
- i_mmap_unlock_write (mapping );
476
- }
477
-
478
- folio_lock (folio );
479
- /*
480
- * We must free the huge page and remove from page
481
- * cache BEFORE removing the region/reserve map
482
- * (hugetlb_unreserve_pages). In rare out of memory
483
- * conditions, removal of the region/reserve map could
484
- * fail. Correspondingly, the subpool and global
485
- * reserve usage count can need to be adjusted.
486
- */
487
- VM_BUG_ON (HPageRestoreReserve (& folio -> page ));
488
- hugetlb_delete_from_page_cache (& folio -> page );
489
- freed ++ ;
490
- if (!truncate_op ) {
491
- if (unlikely (hugetlb_unreserve_pages (inode ,
492
- index , index + 1 , 1 )))
493
- hugetlb_fix_reserve_counts (inode );
494
- }
495
-
496
- folio_unlock (folio );
514
+ if (remove_inode_single_folio (h , inode , mapping , folio ,
515
+ index , truncate_op ))
516
+ freed ++ ;
517
+
497
518
mutex_unlock (& hugetlb_fault_mutex_table [hash ]);
498
519
}
499
520
folio_batch_release (& fbatch );
0 commit comments