On 7/17/23 16:12, Yin Fengwei wrote: > > > On 7/17/23 08:35, Yu Zhao wrote: >> On Sun, Jul 16, 2023 at 6:00 PM Yin, Fengwei <fengwei.yin@xxxxxxxxx> wrote: >>> >>> On 7/15/2023 2:06 PM, Yu Zhao wrote: >>>> There is a problem here that I didn't have the time to elaborate: we >>>> can't mlock() a folio that is within the range but not fully mapped >>>> because this folio can be on the deferred split queue. When the split >>>> happens, those unmapped folios (not mapped by this vma but are mapped >>>> into other vmas) will be stranded on the unevictable lru. >>> >>> This should be fine unless I missed something. During large folio split, >>> the unmap_folio() will be migrate(anon)/unmap(file) folio. Folio will be >>> munlocked in unmap_folio(). So the head/tail pages will be evictable always. >> >> It's close but not entirely accurate: munlock can fail on isolated folios. > > I suppose normal 4K page can hit this problem also and following patch could > fix it: No. This patch is not necessary as unevictable folio will not be picked up by page reclaim. It's not possible to munlock the isolated folio from lru list. The possible cases I am ware are: page_migrate, madvise and damon_pa_pageout and lru_gen_look_around. The first three already handle this case correctly by call folio_putback_lru(). If folio is isolated, the split_folio() will just fail. So looks we are fine for this corner case. Let me know if I miss something here. Regards Yin, Fengwei > > diff --git a/mm/vmscan.c b/mm/vmscan.c > index 1080209a568bb..839b8398aa613 100644 > --- a/mm/vmscan.c > +++ b/mm/vmscan.c > @@ -2498,7 +2498,7 @@ static unsigned int move_folios_to_lru(struct lruvec *lruvec, > > VM_BUG_ON_FOLIO(folio_test_lru(folio), folio); > list_del(&folio->lru); > - if (unlikely(!folio_evictable(folio))) { > + if (unlikely(!folio_evictable(folio) || folio_test_unevictable(folio))) { > spin_unlock_irq(&lruvec->lru_lock); > folio_putback_lru(folio); > spin_lock_irq(&lruvec->lru_lock); > @@ -2723,7 +2723,7 @@ static void shrink_active_list(unsigned long nr_to_scan, > folio = lru_to_folio(&l_hold); > list_del(&folio->lru); > > - if (unlikely(!folio_evictable(folio))) { > + if (unlikely(!folio_evictable(folio) || folio_test_unevictable(folio))) { > folio_putback_lru(folio); > continue; > } > @@ -5182,7 +5182,7 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap > sc->nr_reclaimed += reclaimed; > > list_for_each_entry_safe_reverse(folio, next, &list, lru) { > - if (!folio_evictable(folio)) { > + if (!folio_evictable(folio) || folio_test_unevictable(folio)) { > list_del(&folio->lru); > folio_putback_lru(folio); > continue; > > > > Regards > Yin, Fengwei >