On Thu, Oct 15, 2020 at 2:43 AM Kirill A. Shutemov <kirill@xxxxxxxxxxxxx> wrote: > > Okay, I see what you propose. > > But I don't think it addresses race with try_to_unmap(): I don't think it needs to. Remember: the map_pages() thing is called only for when the page tables are empty. So try_to_unmap() will never see the pte entry, and there is nothing to race with. So sure, it can "race" with try_to_unmap like you say, but who cares? The "race" is no different from taking the page lock _after_ try_to_unmap() already ran (and didn't see anything because the page hadn't been mapped yet). IOW I don't think try_to_unmap() really matters. The race you outline can already happen with the "trylock()" - no different from the trylock just succeeding after the unlock_page(). So you can think of map_pages() as all happening after try_to_unmap() has already succeeded - and didn't see the new pte that hasn't been filled in yet. I do think there is a real race, but it is is with "__remove_mapping()". That still happens under the page lock, but it doesn't actually _depend_ on the page lock as far as I can tell. Because I think the real protection there is that if (!page_ref_freeze(page, refcount)) goto cannot_free; it that code sees "oh, somebody else has a reference to the page, we can't remove the mapping". But it's entirely possible that I don't understand your worry, and I overlooked something. If so, can you explain using smaller words, please ;) Linus