On Wed, Oct 14, 2020 at 09:53:35AM -0700, Linus Torvalds wrote: > In particular, what I _think_ we could do is: > > - lock the page tables > > - check that the page isn't locked > > - increment the page mapcount (atomic and ordered) > > - check that the page still isn't locked > > - insert pte > > without taking the page lock. And the reason that's safe is that *if* > we're racing with something that is about the remove the page mapping, > then *that* code will > > (a) hold the page lock > > (b) before it removes the mapping, it has to remove it from any > existing mappings, which involves checking the mapcount and going off > and getting the page table locks to remove any ptes. > > but my patch did *not* do that, because you have to re-organize things a bit. Okay, I see what you propose. But I don't think it addresses race with try_to_unmap(): CPU0 CPU1 filemap_map_pages() take ptl PageLocked() == false lock_page() try_to_unmap() rwc->done() page_mapcount_is_zero() == true rwc->done() == true, skip full rmap walk never take ptl taken by CPU0 try_to_unmap() == true ... unlock_page() increment mapcount PageLocked() == false insert PTE Are we willing to give up rwc->done() optimization? Or do I miss some other serialization point? -- Kirill A. Shutemov