On 10/12/18 8:55 PM, Dave Chinner wrote: > On Thu, Oct 11, 2018 at 11:00:12PM -0700, john.hubbard@xxxxxxxxx wrote: >> From: John Hubbard <jhubbard@xxxxxxxxxx> [...] >> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h >> index 5ed8f6292a53..017ab82e36ca 100644 >> --- a/include/linux/mm_types.h >> +++ b/include/linux/mm_types.h >> @@ -78,12 +78,22 @@ struct page { >> */ >> union { >> struct { /* Page cache and anonymous pages */ >> - /** >> - * @lru: Pageout list, eg. active_list protected by >> - * zone_lru_lock. Sometimes used as a generic list >> - * by the page owner. >> - */ >> - struct list_head lru; >> + union { >> + /** >> + * @lru: Pageout list, eg. active_list protected >> + * by zone_lru_lock. Sometimes used as a >> + * generic list by the page owner. >> + */ >> + struct list_head lru; >> + /* Used by get_user_pages*(). Pages may not be >> + * on an LRU while these dma_pinned_* fields >> + * are in use. >> + */ >> + struct { >> + unsigned long dma_pinned_flags; >> + atomic_t dma_pinned_count; >> + }; >> + }; > > Isn't this broken for mapped file-backed pages? i.e. they may be > passed as the user buffer to read/write direct IO and so the pages > passed to gup will be on the active/inactive LRUs. hence I can't see > how you can have dual use of the LRU list head like this.... > > What am I missing here? Hi Dave, In patch 6/6, pin_page_for_dma(), which is called at the end of get_user_pages(), unceremoniously rips the pages out of the LRU, as a prerequisite to using either of the page->dma_pinned_* fields. The idea is that LRU is not especially useful for this situation anyway, so we'll just make it one or the other: either a page is dma-pinned, and just hanging out doing RDMA most likely (and LRU is less meaningful during that time), or it's possibly on an LRU list. -- thanks, John Hubbard NVIDIA