On Wed, Sep 29, 2021 at 12:50:15PM +0100, Joao Martins wrote: > > If the get_dev_pagemap has to remain then it just means we have to > > flush before changing pagemap pointers > Right -- I don't think we should need it as that discussion on the other > thread goes. > > OTOH, using @pgmap might be useful to unblock gup-fast FOLL_LONGTERM > for certain devmap types[0] (like MEMORY_DEVICE_GENERIC [device-dax] > can support it but not MEMORY_DEVICE_FSDAX [fsdax]). When looking at Logan's patches I think it is pretty clear to me that page->pgmap must never be a dangling pointer if the caller has a legitimate refcount on the page. For instance the migrate and stuff all blindly calls is_device_private_page() on the struct page expecting a valid page->pgmap. This also looks like it is happening, ie void __put_page(struct page *page) { if (is_zone_device_page(page)) { put_dev_pagemap(page->pgmap); Is indeed putting the pgmap ref back when the page becomes ungettable. This properly happens when the page refcount goes to zero and so it should fully interlock with __page_cache_add_speculative(): if (unlikely(!page_ref_add_unless(page, count, 0))) { Thus, in gup.c, if we succeed at try_grab_compound_head() then page->pgmap is a stable pointer with a valid refcount. So, all the external pgmap stuff in gup.c is completely pointless. try_grab_compound_head() provides us with an equivalent protection at lower cost. Remember gup.c doesn't deref the pgmap at all. Dan/Alistair/Felix do you see any hole in that argument?? So lets just delete it! Jason