From: Ryan Roberts <ryan.roberts@arm.com>
To: "Russell King (Oracle)" <linux@armlinux.org.uk>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>,
kernel test robot <lkp@intel.com>,
linux-mm@kvack.org, llvm@lists.linux.dev,
oe-kbuild-all@lists.linux.dev,
Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@redhat.com>,
"Mike Rapoport (IBM)" <rppt@kernel.org>,
Arnd Bergmann <arnd@arndb.de>,
x86@kernel.org, linux-m68k@lists.linux-m68k.org,
linux-fsdevel@vger.kernel.org, kasan-dev@googlegroups.com,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
Dimitri Sivanich <dimitri.sivanich@hpe.com>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Muchun Song <muchun.song@linux.dev>,
Andrey Ryabinin <ryabinin.a.a@gmail.com>,
Miaohe Lin <linmiaohe@huawei.com>,
Dennis Zhou <dennis@kernel.org>, Tejun Heo <tj@kernel.org>,
Christoph Lameter <cl@linux-foundation.org>,
Uladzislau Rezki <urezki@gmail.com>,
Christoph Hellwig <hch@infradead.org>
Subject: Re: [PATCH V2 7/7] mm: Use pgdp_get() for accessing PGD entries
Date: Thu, 19 Sep 2024 19:49:09 +0200 [thread overview]
Message-ID: <5bd51798-cb47-4a7b-be40-554b5a821fe7@arm.com> (raw)
In-Reply-To: <ZuxZ/QeSdqTHtfmw@shell.armlinux.org.uk>
On 19/09/2024 18:06, Russell King (Oracle) wrote:
> On Thu, Sep 19, 2024 at 05:48:58PM +0200, Ryan Roberts wrote:
>>> 32-bit arm uses, in some circumstances, an array because each level 1
>>> page table entry is actually two descriptors. It needs to be this way
>>> because each level 2 table pointed to by each level 1 entry has 256
>>> entries, meaning it only occupies 1024 bytes in a 4096 byte page.
>>>
>>> In order to cut down on the wastage, treat the level 1 page table as
>>> groups of two entries, which point to two consecutive 1024 byte tables
>>> in the level 2 page.
>>>
>>> The level 2 entry isn't suitable for the kernel's use cases (there are
>>> no bits to represent accessed/dirty and other important stuff that the
>>> Linux MM wants) so we maintain the hardware page tables and a separate
>>> set that Linux uses in the same page. Again, the software tables are
>>> consecutive, so from Linux's perspective, the level 2 page tables
>>> have 512 entries in them and occupy one full page.
>>>
>>> This is documented in arch/arm/include/asm/pgtable-2level.h
>>>
>>> However, what this means is that from the software perspective, the
>>> level 1 page table descriptors are an array of two entries, both of
>>> which need to be setup when creating a level 2 page table, but only
>>> the first one should ever be dereferenced when walking the tables,
>>> otherwise the code that walks the second level of page table entries
>>> will walk off the end of the software table into the actual hardware
>>> descriptors.
>>>
>>> I've no idea what the idea is behind introducing pgd_get() and what
>>> it's semantics are, so I can't comment further.
>>
>> The helper is intended to read the value of the entry pointed to by the passed
>> in pointer. And it shoiuld be read in a "single copy atomic" manner, meaning no
>> tearing. Further, the PTL is expected to be held when calling the getter. If the
>> HW can write to the entry such that its racing with the lock holder (i.e. HW
>> update of access/dirty) then READ_ONCE() should be suitable for most
>> architectures. If there is no possibility of racing (because HW doesn't write to
>> the entry), then a simple dereference would be sufficient, I think (which is
>> what the core code was already doing in most cases).
>
> The core code should be making no access to the PGD entries on 32-bit
> ARM since the PGD level does not exist. Writes are done at PMD level
> in arch code. Reads are done by core code at PMD level.
>
> It feels to me like pgd_get() just doesn't fit the model to which 32-bit
> ARM was designed to use decades ago, so I want full details about what
> pgd_get() is going to be used for and how it is going to be used,
> because I feel completely in the dark over this new development. I fear
> that someone hasn't understood the Linux page table model if they're
> wanting to access stuff at levels that effectively "aren't implemented"
> in the architecture specific kernel model of the page tables.
This change isn't as big and scary as I think you fear. The core-mm today
dereferences pgd pointers (and p4d, pud, pmd pointers) directly in its code. See
follow_pfnmap_start(), gup_fast_pgd_leaf(), and many other sites. These changes
aim to abstract those dereferences into an inline function that the architecture
can override and implement if it so wishes.
The core-mm implements default versions of these helper functions which do
READ_ONCE(), but does not currently use them consistently.
From Anshuman's comments earlier in this thread, it looked to me like the arm
pgd_t type is too big to read with READ_ONCE() - it can't be atomically read on
that arch. So my proposal was to implement the override for arm to do exactly
what the core-mm used to do, which is a pointer dereference. So that would
result in exact same behaviour for the arm arch.
>
> Essentially, on 32-bit 2-level ARM, the PGD is merely indexed by the
> virtual address. As far as the kernel is concerned, each entry is
> 64-bit, and the generic kernel code has no business accessing that
> through the pgd pointer.
>
> The pgd pointer is passed through the PUD and PMD levels, where it is
> typecast down through the kernel layers to a pmd_t pointer, where it
> becomes a 32-bit quantity. This results in only the _first_ level 1
> pointer being dereferenced by kernel code to a 32-bit pmd_t quantity.
> pmd_page_vaddr() converts this pmd_t quantity to a pte pointer (which
> points at the software level 2 page tables, not the hardware page
> tables.)
As an aside, my understanding of Linux's pgtable model differs from what you
describe. As I understand it, Linux's logical page table model has 5 levels
(pgd, p4d, pud, pmd, pte). If an arch doesn't support all 5 levels, then the
middle levels can be folded away (p4d first, then pud, then pmd). But the
core-mm still logically walks all 5 levels. So if the HW supports 2 levels,
those levels are (pgd, pte). But you are suggesting that arm exposes pmd and
pte, which is not what Linux expects? (Perhaps you call it the pmd in the arch,
but that is being folded and accessed through the pgd helpers in core code, I
believe?
>
> So, as I'm now being told that the kernel wants to dereference the
> pgd level despite the model I describe above, alarm bells are ringing.
> I want full information please.
>
This is not new; the kernel already dereferences the pgd pointers.
Thanks,
Ryan
next prev parent reply other threads:[~2024-09-19 17:49 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-17 7:31 [PATCH V2 0/7] mm: Use pxdp_get() for accessing page table entries Anshuman Khandual
2024-09-17 7:31 ` [PATCH V2 1/7] m68k/mm: Change pmd_val() Anshuman Khandual
2024-09-17 8:40 ` Ryan Roberts
2024-09-17 10:20 ` David Hildenbrand
2024-09-17 10:27 ` Ryan Roberts
2024-09-17 10:30 ` David Hildenbrand
2024-09-17 7:31 ` [PATCH V2 2/7] x86/mm: Drop page table entry address output from pxd_ERROR() Anshuman Khandual
2024-09-17 10:22 ` David Hildenbrand
2024-09-17 11:19 ` Dave Hansen
2024-09-17 11:25 ` Anshuman Khandual
2024-09-17 11:31 ` David Hildenbrand
2024-09-17 7:31 ` [PATCH V2 3/7] mm: Use ptep_get() for accessing PTE entries Anshuman Khandual
2024-09-17 8:44 ` Ryan Roberts
2024-09-17 10:28 ` David Hildenbrand
2024-09-18 6:32 ` Anshuman Khandual
2024-09-19 8:04 ` David Hildenbrand
2024-09-19 9:20 ` Anshuman Khandual
2024-09-17 7:31 ` [PATCH V2 4/7] mm: Use pmdp_get() for accessing PMD entries Anshuman Khandual
2024-09-17 10:05 ` Ryan Roberts
2024-09-18 18:57 ` kernel test robot
2024-09-19 7:21 ` Anshuman Khandual
2024-09-18 19:07 ` kernel test robot
2024-09-19 7:12 ` Anshuman Khandual
2024-09-17 7:31 ` [PATCH V2 5/7] mm: Use pudp_get() for accessing PUD entries Anshuman Khandual
2024-09-17 7:31 ` [PATCH V2 6/7] mm: Use p4dp_get() for accessing P4D entries Anshuman Khandual
2024-09-17 7:31 ` [PATCH V2 7/7] mm: Use pgdp_get() for accessing PGD entries Anshuman Khandual
2024-09-18 20:30 ` kernel test robot
2024-09-19 7:55 ` Anshuman Khandual
2024-09-19 9:11 ` Russell King (Oracle)
2024-09-19 15:48 ` Ryan Roberts
2024-09-19 17:06 ` Russell King (Oracle)
2024-09-19 17:49 ` Ryan Roberts [this message]
2024-09-19 20:25 ` Russell King (Oracle)
2024-09-20 6:57 ` Ryan Roberts
2024-09-20 9:47 ` Russell King (Oracle)
2024-09-23 15:21 ` Ryan Roberts
2024-09-25 10:05 ` [PATCH V2 0/7] mm: Use pxdp_get() for accessing page table entries Christophe Leroy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5bd51798-cb47-4a7b-be40-554b5a821fe7@arm.com \
--to=ryan.roberts@arm.com \
--cc=akpm@linux-foundation.org \
--cc=anshuman.khandual@arm.com \
--cc=arnd@arndb.de \
--cc=cl@linux-foundation.org \
--cc=david@redhat.com \
--cc=dennis@kernel.org \
--cc=dimitri.sivanich@hpe.com \
--cc=hch@infradead.org \
--cc=kasan-dev@googlegroups.com \
--cc=linmiaohe@huawei.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-m68k@lists.linux-m68k.org \
--cc=linux-mm@kvack.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=lkp@intel.com \
--cc=llvm@lists.linux.dev \
--cc=muchun.song@linux.dev \
--cc=oe-kbuild-all@lists.linux.dev \
--cc=rppt@kernel.org \
--cc=ryabinin.a.a@gmail.com \
--cc=tj@kernel.org \
--cc=urezki@gmail.com \
--cc=viro@zeniv.linux.org.uk \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox