On 09.05.22 10:51, Miaohe Lin wrote: > On 2022/4/29 18:07, David Hildenbrand wrote: >> On 25.04.22 15:27, Miaohe Lin wrote: >>> When non-lru movable page was freed from under us, __ClearPageMovable must >>> have been done. Even if it's not done, ClearPageIsolated here won't hurt >>> as page will be freed anyway. So we can thus remove unneeded lock page and >>> PageMovable check here. >>> >>> Signed-off-by: Miaohe Lin <linmiaohe@xxxxxxxxxx> >>> Reviewed-by: Christoph Hellwig <hch@xxxxxx> >>> --- >>> mm/migrate.c | 8 ++------ >>> 1 file changed, 2 insertions(+), 6 deletions(-) >>> >>> diff --git a/mm/migrate.c b/mm/migrate.c >>> index b779646665fe..0fc4651b3e39 100644 >>> --- a/mm/migrate.c >>> +++ b/mm/migrate.c >>> @@ -1093,12 +1093,8 @@ static int unmap_and_move(new_page_t get_new_page, >>> /* page was freed from under us. So we are done. */ >>> ClearPageActive(page); >>> ClearPageUnevictable(page); >>> - if (unlikely(__PageMovable(page))) { >>> - lock_page(page); >>> - if (!PageMovable(page)) >>> - ClearPageIsolated(page); >>> - unlock_page(page); >>> - } >>> + if (unlikely(__PageMovable(page))) >>> + ClearPageIsolated(page); >>> goto out; >>> } >> >> Hm, that code+change raises a couple of questions. >> >> We're doing here the same as in putback_movable_pages(). So I guess the >> difference here is that the caller did release the reference while the >> page was isolated, while we don't assume the same in >> putback_movable_pages(). > > Agree. > >> >> >> Shouldn't whoever owned the page have cleared that? IOW, is it even >> valid that we see a movable or isolated page here (WARN/BUG?)? >> >> At least for balloon compaction, I remember that __PageMovable() is >> properly cleared before freeing it via balloon_page_delete(). > > z3fold, zsmalloc will do __ClearPageMovable when the page is going to be released. > So I think we shouldn't see a movable page here: > > void __ClearPageMovable(struct page *page) > { > VM_BUG_ON_PAGE(!PageMovable(page), page); > /* > * Clear registered address_space val with keeping PAGE_MAPPING_MOVABLE > * flag so that VM can catch up released page by driver after isolation. > * With it, VM migration doesn't try to put it back. > */ > page->mapping = (void *)((unsigned long)page->mapping & > PAGE_MAPPING_MOVABLE); > } > > But it seems there is no guarantee for PageIsolated flag. Or am I miss something? At least the code we have now: if (unlikely(__PageMovable(page))) ClearPageIsolated(page); Should be dead code. So PG_isolated could remain set. If PG_isolated is still set, it will get cleared in the buddy when freeing the page via page->flags &= ~PAGE_FLAGS_CHECK_AT_PREP; > >> >> >> Also, I am not sure how reliable that page count check is here: if we'd >> have another speculative reference to the page, we might see >> "page_count(page) > 1" and not take that path, although the previous >> owner released the last reference. > > IIUC, there should not be such speculative reference. The driver should have taken care > of it. How can you prevent any kind of speculative references? See isolate_movable_page() as an example, which grabs a speculative reference to then find out that the page is already isolated by someone else, to then back off. -- Thanks, David / dhildenb