On Tue, Mar 24, 2015 at 03:54:00PM -0700, Hugh Dickins wrote: > On Mon, 23 Mar 2015, Kirill A. Shutemov wrote: > > Should we avoid dirtying them in the first place? > > I don't think so: to do so would add more branches in hot paths, > just to avoid a rare case which works fine without them; and > prevent a driver from using it, in the unlikely case that's so. It's branches vs. useless atomic oprations. > > GUP pin would screw up page_mapcount() on these pages. It would affect > > memory stats for the process and probably something else. > > Yes, the GUP pin would increment page_mapcount() without an additional > mapping - but can only happen once the page has already been mapped, > so FILE_MAPPED stats unaffected? I'm not sure; but surely it wouldn't > work as well when unmapped before unpinned, since the unmapping will > see "still mapped" and the unpinning won't do anything with FILE_MAPPED. > > Unmapping before unpinning is an uncommon path; but it can't be ignored, > it is the path which demanded __GFP_COMP in the first place. > > Looks like extending THP by-mapcount refcounting to other compound pages > was not such a good idea. But since nobody has noticed, we may not need > a more urgent fix than your simplification of THP refcounting. I think PSS and /proc/kpagecount are broken by this. > > I think we can get __compound_tail_refcounted() ignore these pages by > > checking if page->mapping is NULL. > > I forget what's in page->mapping on the THP tails. NULL. We never set ->mapping on any tail pages. That's why I want outlaw using that value: it's just doesn't match with head page ->mapping for some of compound pages. And for others it matches just because nobody touches it for any subpage. > Or do you mean page->mapping of head? It would be better not to rely on > that, I'm not certain that no driver could set page->mapping of compound > head. There's probably some field or flag on the tails that you could > use; but I don't know that it's needed in a hurry. We only need tail refcounting for THP, so I think this should fix the issue: diff --git a/include/linux/mm.h b/include/linux/mm.h index 4a3a38522ab4..9ab432660adb 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -456,7 +456,7 @@ static inline int page_count(struct page *page) static inline bool __compound_tail_refcounted(struct page *page) { - return !PageSlab(page) && !PageHeadHuge(page); + return !PageSlab(page) && !PageHeadHuge(page) && PageAnon(page); } /* -- Kirill A. Shutemov -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>