From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754828AbbK3QZl (ORCPT ); Mon, 30 Nov 2015 11:25:41 -0500 Received: from www.sr71.net ([198.145.64.142]:55910 "EHLO blackbird.sr71.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753974AbbK3QZe (ORCPT ); Mon, 30 Nov 2015 11:25:34 -0500 Subject: Re: [PATCH 19/37] x86, mm: simplify get_user_pages() PTE bit handling To: Thomas Gleixner References: <20151117033511.BFFA1440@viggo.jf.intel.com> <20151117033537.C2DBB366@viggo.jf.intel.com> Cc: linux-kernel@vger.kernel.org, x86@kernel.org, dave.hansen@linux.intel.com From: Dave Hansen Message-ID: <565C787D.9090806@sr71.net> Date: Mon, 30 Nov 2015 08:25:33 -0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 11/27/2015 02:12 AM, Thomas Gleixner wrote: > On Mon, 16 Nov 2015, Dave Hansen wrote: >> +static inline int pte_allows_gup(pte_t pte, int write) >> +{ >> + /* >> + * 'entry_flags' can come from a pte, pmd or pud. Make >> + * sure to only check flags here that are valid *and* the >> + * same value on all 3 types. (PAT is currently the only >> + * one where that is true and is not checked here). > > I have a hard time to understand that comment. > > /* > * 'entry_flags' can come from a pte, pmd or pud. We only check > * _PAGE_PRESENT, _PAGE_USER and _PAGE_RW here, which are the > * same for all types. > */ > > Is that what you wanted to say? Yeah, that's a much better way to say it. I'll fix it up. >> + */ >> + if (!(pte_flags(pte) & (_PAGE_PRESENT|_PAGE_USER))) >> + return 0; >> + if (write && !(pte_write(pte))) >> + return 0; >> + return 1; >> +} >> + >> +static inline int pmd_allows_gup(pmd_t pmd, int write) >> +{ >> + return pte_allows_gup(*(pte_t *)&pmd, write); >> +} >> + >> +static inline int pud_allows_gup(pud_t pud, int write) >> +{ >> + return pte_allows_gup(*(pte_t *)&pud, write); >> +} >> + > >> static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, >> unsigned long end, int write, struct page **pages, int *nr) >> { >> - unsigned long mask; >> struct page *head, *page; >> int refs; >> >> - mask = _PAGE_PRESENT|_PAGE_USER; >> - if (write) >> - mask |= _PAGE_RW; >> - if ((pmd_flags(pmd) & mask) != mask) >> + if (!pmd_allows_gup(pmd, write)) > > Why do you need that extra indirection here of rereading the pmd? > You have the pmd already. The intention there was not to re-read the PMD, but only to cast the structure over to a pte_t. I expected the compiler to be able to figure out what was going on and not actually re-read anything. Is that a bad assumption?