On 07/03/2018 10:48 AM, Christopher Lameter wrote: > On Tue, 3 Jul 2018, John Hubbard wrote: > >> The page->_refcount field is used normally, in addition to the >> dma_pinned_count. >> But the problem is that, unless the caller knows what kind of page it is, >> the page->dma_pinned_count cannot be looked at, because it is unioned with >> page->lru.prev. page->dma_pinned_flags, at least starting at bit 1, are >> safe to look at due to pointer alignment, but now you cannot atomically >> count... >> >> So this seems unsolvable without having the caller specify that it knows the >> page type, and that it is therefore safe to decrement page->dma_pinned_count. >> I was hoping I'd found a way, but clearly I haven't. :) > > Try to find some way to indicate that the page is pinned by using some of > the existing page flags? There is already an MLOCK flag. Maybe some > creativity with that can lead to something (but then the MLOCKed pages are > on the unevictable LRU....). cgroups used to have something called struct > page_ext. Oh its there in linux/mm/page_ext.c. >
Yes, that would provide just a touch more cabability: we could both read and write a dma-pinned page(_ext) flag safely, instead of only being able to just read. I'm doubt that that's enough additional information, though. The general problem of allowing random put_page() calls to decrement the dma-pinned count (see Jan's diagram at the beginning of this thread) cannot be solved by anything less than some sort of "who (or which special type of caller, at least) owns this page" approach, as far as I can see. The put_user_pages() provides arguably the simplest version of that kind of solution. Also, even just using a single bit from page extensions would cost some extra memory, because for example on 64-bit systems many configurations do not need the additional flags that page_ext.h provides, so they return "false" from the page_ext_operations.need() callback. Changing get_user_pages to require page extensions would lead to *every* configuration requiring page extensions, so 64-bit users would lose some memory for sure. On the other hand, it avoids the "take page off of the LRU" complexity that I've got here. But again, I don't think a single flag, or even a count, would actually solve the problem.