| @@ -3455,23 +3455,6 @@ static void lru_add_split_folio(struct folio *folio, struct folio *new_folio, · 3454 unmodified lines |
| 3455 | } | 3455 | } |
| 3456 | } | 3456 | } |
| 3457 | | 3457 | |
| 3458 | /* Racy check whether the huge page can be split */ | | |
| 3459 | bool can_split_folio(struct folio *folio, int caller_pins, int *pextra_pins) | | |
| 3460 | { | | |
| 3461 | int extra_pins; | | |
| 3462 | | | |
| 3463 | /* Additional pins from page cache */ | | |
| 3464 | if (folio_test_anon(folio)) | | |
| 3465 | extra_pins = folio_test_swapcache(folio) ? | | |
| 3466 | folio_nr_pages(folio) : 0; | | |
| 3467 | else | | |
| 3468 | extra_pins = folio_nr_pages(folio); | | |
| 3469 | if (pextra_pins) | | |
| 3470 | *pextra_pins = extra_pins; | | |
| 3471 | return folio_mapcount(folio) == folio_ref_count(folio) - extra_pins - | | |
| 3472 | caller_pins; | | |
| 3473 | } | | |
| 3474 | | | |
| 3475 | static bool page_range_has_hwpoisoned(struct page *page, long nr_pages) | 3458 | static bool page_range_has_hwpoisoned(struct page *page, long nr_pages) |
| 3476 | { | 3459 | { |
| 3477 | for (; nr_pages; page++, nr_pages--) | 3460 | for (; nr_pages; page++, nr_pages--) |
| @@ -3767,11 +3750,19 @@ int folio_check_splittable(struct folio *folio, unsigned int new_order, · 289 unmodified lines |
| 3767 | return 0; | 3750 | return 0; |
| 3768 | } | 3751 | } |
| 3769 | | 3752 | |
| | 3753 | /* Number of folio references from the pagecache or the swapcache. */ |
| | 3754 | static unsigned int folio_cache_ref_count(const struct folio *folio) |
| | 3755 | { |
| | 3756 | if (folio_test_anon(folio) && !folio_test_swapcache(folio)) |
| | 3757 | return 0; |
| | 3758 | return folio_nr_pages(folio); |
| | 3759 | } |
| | 3760 | |
| 3770 | static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int new_order, | 3761 | static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int new_order, |
| 3771 | struct page *split_at, struct xa_state *xas, | 3762 | struct page *split_at, struct xa_state *xas, |
| 3772 | struct address_space *mapping, bool do_lru, | 3763 | struct address_space *mapping, bool do_lru, |
| 3773 | struct list_head *list, enum split_type split_type, | 3764 | struct list_head *list, enum split_type split_type, |
| 3774 | pgoff_t end, int *nr_shmem_dropped, int extra_pins) | 3765 | pgoff_t end, int *nr_shmem_dropped) |
| 3775 | { | 3766 | { |
| 3776 | struct folio *end_folio = folio_next(folio); | 3767 | struct folio *end_folio = folio_next(folio); |
| 3777 | struct folio *new_folio, *next; | 3768 | struct folio *new_folio, *next; |
| @@ -3782,10 +3773,9 @@ static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int n · 4 unmodified lines |
| 3782 | VM_WARN_ON_ONCE(!mapping && end); | 3773 | VM_WARN_ON_ONCE(!mapping && end); |
| 3783 | /* Prevent deferred_split_scan() touching ->_refcount */ | 3774 | /* Prevent deferred_split_scan() touching ->_refcount */ |
| 3784 | ds_queue = folio_split_queue_lock(folio); | 3775 | ds_queue = folio_split_queue_lock(folio); |
| 3785 | if (folio_ref_freeze(folio, 1 + extra_pins)) { | 3776 | if (folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) { |
| 3786 | struct swap_cluster_info *ci = NULL; | 3777 | struct swap_cluster_info *ci = NULL; |
| 3787 | struct lruvec *lruvec; | 3778 | struct lruvec *lruvec; |
| 3788 | int expected_refs; | | |
| 3789 | | 3779 | |
| 3790 | if (old_order > 1) { | 3780 | if (old_order > 1) { |
| 3791 | if (!list_empty(&folio->_deferred_list)) { | 3781 | if (!list_empty(&folio->_deferred_list)) { |
| @@ -3853,8 +3843,8 @@ static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int n · 61 unmodified lines |
| 3853 | | 3843 | |
| 3854 | zone_device_private_split_cb(folio, new_folio); | 3844 | zone_device_private_split_cb(folio, new_folio); |
| 3855 | | 3845 | |
| 3856 | expected_refs = folio_expected_ref_count(new_folio) + 1; | 3846 | folio_ref_unfreeze(new_folio, |
| 3857 | folio_ref_unfreeze(new_folio, expected_refs); | 3847 | folio_cache_ref_count(new_folio) + 1); |
| 3858 | | 3848 | |
| 3859 | if (do_lru) | 3849 | if (do_lru) |
| 3860 | lru_add_split_folio(folio, new_folio, lruvec, list); | 3850 | lru_add_split_folio(folio, new_folio, lruvec, list); |
| @@ -3897,8 +3887,7 @@ static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int n · 36 unmodified lines |
| 3897 | * Otherwise, a parallel folio_try_get() can grab @folio | 3887 | * Otherwise, a parallel folio_try_get() can grab @folio |
| 3898 | * and its caller can see stale page cache entries. | 3888 | * and its caller can see stale page cache entries. |
| 3899 | */ | 3889 | */ |
| 3900 | expected_refs = folio_expected_ref_count(folio) + 1; | 3890 | folio_ref_unfreeze(folio, folio_cache_ref_count(folio) + 1); |
| 3901 | folio_ref_unfreeze(folio, expected_refs); | | |
| 3902 | | 3891 | |
| 3903 | if (do_lru) | 3892 | if (do_lru) |
| 3904 | unlock_page_lruvec(lruvec); | 3893 | unlock_page_lruvec(lruvec); |
| @@ -3947,7 +3936,7 @@ static int __folio_split(struct folio *folio, unsigned int new_order, · 42 unmodified lines |
| 3947 | struct folio *new_folio, *next; | 3936 | struct folio *new_folio, *next; |
| 3948 | int nr_shmem_dropped = 0; | 3937 | int nr_shmem_dropped = 0; |
| 3949 | int remap_flags = 0; | 3938 | int remap_flags = 0; |
| 3950 | int extra_pins, ret; | 3939 | int ret; |
| 3951 | pgoff_t end = 0; | 3940 | pgoff_t end = 0; |
| 3952 | | 3941 | |
| 3953 | VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio); | 3942 | VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio); |
| @@ -4028,7 +4017,7 @@ static int __folio_split(struct folio *folio, unsigned int new_order, · 74 unmodified lines |
| 4028 | * Racy check if we can split the page, before unmap_folio() will | 4017 | * Racy check if we can split the page, before unmap_folio() will |
| 4029 | * split PMDs | 4018 | * split PMDs |
| 4030 | */ | 4019 | */ |
| 4031 | if (!can_split_folio(folio, 1, &extra_pins)) { | 4020 | if (folio_expected_ref_count(folio) != folio_ref_count(folio) - 1) { |
| 4032 | ret = -EAGAIN; | 4021 | ret = -EAGAIN; |
| 4033 | goto out_unlock; | 4022 | goto out_unlock; |
| 4034 | } | 4023 | } |
| @@ -4051,8 +4040,7 @@ static int __folio_split(struct folio *folio, unsigned int new_order, · 16 unmodified lines |
| 4051 | } | 4040 | } |
| 4052 | | 4041 | |
| 4053 | ret = __folio_freeze_and_split_unmapped(folio, new_order, split_at, &xas, mapping, | 4042 | ret = __folio_freeze_and_split_unmapped(folio, new_order, split_at, &xas, mapping, |
| 4054 | true, list, split_type, end, &nr_shmem_dropped, | 4043 | true, list, split_type, end, &nr_shmem_dropped); |
| 4055 | extra_pins); | | |
| 4056 | fail: | 4044 | fail: |
| 4057 | if (mapping) | 4045 | if (mapping) |
| 4058 | xas_unlock(&xas); | 4046 | xas_unlock(&xas); |
| @@ -4126,20 +4114,20 @@ out: · 67 unmodified lines |
| 4126 | */ | 4114 | */ |
| 4127 | int folio_split_unmapped(struct folio *folio, unsigned int new_order) | 4115 | int folio_split_unmapped(struct folio *folio, unsigned int new_order) |
| 4128 | { | 4116 | { |
| 4129 | int extra_pins, ret = 0; | 4117 | int ret = 0; |
| 4130 | | 4118 | |
| 4131 | VM_WARN_ON_ONCE_FOLIO(folio_mapped(folio), folio); | 4119 | VM_WARN_ON_ONCE_FOLIO(folio_mapped(folio), folio); |
| 4132 | VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio); | 4120 | VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio); |
| 4133 | VM_WARN_ON_ONCE_FOLIO(!folio_test_large(folio), folio); | 4121 | VM_WARN_ON_ONCE_FOLIO(!folio_test_large(folio), folio); |
| 4134 | VM_WARN_ON_ONCE_FOLIO(!folio_test_anon(folio), folio); | 4122 | VM_WARN_ON_ONCE_FOLIO(!folio_test_anon(folio), folio); |
| 4135 | | 4123 | |
| 4136 | if (!can_split_folio(folio, 1, &extra_pins)) | 4124 | if (folio_expected_ref_count(folio) != folio_ref_count(folio) - 1) |
| 4137 | return -EAGAIN; | 4125 | return -EAGAIN; |
| 4138 | | 4126 | |
| 4139 | local_irq_disable(); | 4127 | local_irq_disable(); |
| 4140 | ret = __folio_freeze_and_split_unmapped(folio, new_order, &folio->page, NULL, | 4128 | ret = __folio_freeze_and_split_unmapped(folio, new_order, &folio->page, NULL, |
| 4141 | NULL, false, NULL, SPLIT_TYPE_UNIFORM, | 4129 | NULL, false, NULL, SPLIT_TYPE_UNIFORM, |
| 4142 | 0, NULL, extra_pins); | 4130 | 0, NULL); |
| 4143 | local_irq_enable(); | 4131 | local_irq_enable(); |
| 4144 | return ret; | 4132 | return ret; |
| 4145 | } | 4133 | } |
| @@ -4632,7 +4620,7 @@ static int split_huge_pages_pid(int pid, unsigned long vaddr_start, · 486 unmodified lines |
| 4632 | * can be split or not. So skip the check here. | 4620 | * can be split or not. So skip the check here. |
| 4633 | */ | 4621 | */ |
| 4634 | if (!folio_test_private(folio) && | 4622 | if (!folio_test_private(folio) && |
| 4635 | !can_split_folio(folio, 0, NULL)) | 4623 | folio_expected_ref_count(folio) != folio_ref_count(folio)) |
| 4636 | goto next; | 4624 | goto next; |
| 4637 | | 4625 | |
| 4638 | if (!folio_trylock(folio)) | 4626 | if (!folio_trylock(folio)) |