From: Chih-En Lin <shiyn.lin@gmail.com>
To: David Hildenbrand <david@redhat.com>
Cc: Nadav Amit <namit@vmware.com>,
Andrew Morton <akpm@linux-foundation.org>,
Qi Zheng <zhengqi.arch@bytedance.com>,
Matthew Wilcox <willy@infradead.org>,
Christophe Leroy <christophe.leroy@csgroup.eu>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-mm@kvack.org" <linux-mm@kvack.org>,
Luis Chamberlain <mcgrof@kernel.org>,
Kees Cook <keescook@chromium.org>,
Iurii Zaikin <yzaikin@google.com>,
Vlastimil Babka <vbabka@suse.cz>,
William Kucharski <william.kucharski@oracle.com>,
"Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>,
Peter Xu <peterx@redhat.com>,
Suren Baghdasaryan <surenb@google.com>,
Arnd Bergmann <arnd@arndb.de>,
Tong Tiangen <tongtiangen@huawei.com>,
Pasha Tatashin <pasha.tatashin@soleen.com>,
Li kunyu <kunyu@nfschina.com>,
Anshuman Khandual <anshuman.khandual@arm.com>,
Minchan Kim <minchan@kernel.org>, Yang Shi <shy828301@gmail.com>,
Song Liu <song@kernel.org>, Miaohe Lin <linmiaohe@huawei.com>,
Thomas Gleixner <tglx@linutronix.de>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Andy Lutomirski <luto@kernel.org>,
Fenghua Yu <fenghua.yu@intel.com>,
Dinglan Peng <peng301@purdue.edu>,
Pedro Fonseca <pfonseca@purdue.edu>,
Jim Huang <jserv@ccns.ncku.edu.tw>,
Huichun Feng <foxhoundsk.tw@gmail.com>
Subject: Re: [RFC PATCH v2 9/9] mm: Introduce Copy-On-Write PTE table
Date: Fri, 30 Sep 2022 02:57:40 +0800 [thread overview]
Message-ID: <YzXqpN5bnG9HSGyI@strix-laptop> (raw)
In-Reply-To: <834c258d-4c0e-1753-3608-8a7e28c14d07@redhat.com>
On Thu, Sep 29, 2022 at 08:38:52PM +0200, David Hildenbrand wrote:
> On 29.09.22 20:29, Chih-En Lin wrote:
> > On Thu, Sep 29, 2022 at 07:24:31PM +0200, David Hildenbrand wrote:
> > > > > IMHO, a relaxed form that focuses on only the memory consumption reduction
> > > > > could *possibly* be accepted upstream if it's not too invasive or complex.
> > > > > During fork(), we'd do exactly what we used to do to PTEs (increment
> > > > > mapcount, refcount, trying to clear PageAnonExclusive, map the page R/O,
> > > > > duplicate swap entries; all while holding the page table lock), however,
> > > > > sharing the prepared page table with the child process using COW after we
> > > > > prepared it.
> > > > >
> > > > > Any (most once we want to *optimize* rmap handling) modification attempts
> > > > > require breaking COW -- copying the page table for the faulting process. But
> > > > > at that point, the PTEs are already write-protected and properly accounted
> > > > > (refcount/mapcount/PageAnonExclusive).
> > > > >
> > > > > Doing it that way might not require any questionable GUP hacks and swapping,
> > > > > MMU notifiers etc. "might just work as expected" because the accounting
> > > > > remains unchanged" -- we simply de-duplicate the page table itself we'd have
> > > > > after fork and any modification attempts simply replace the mapped copy.
> > > >
> > > > Agree.
> > > > However for GUP hacks, if we want to do the COW to page table, we still
> > > > need the hacks in this patch (using the COW_PTE_OWN_EXCLUSIVE flag to
> > > > check whether the PTE table is available or not before we do the COW to
> > > > the table). Otherwise, it will be more complicated since it might need
> > > > to handle situations like while preparing the COW work, it just figuring
> > > > out that it needs to duplicate the whole table and roll back (recover
> > > > the state and copy it to new table). Hopefully, I'm not wrong here.
> > >
> > > The nice thing is that GUP itself *usually* doesn't modify page tables. One
> > > corner case is follow_pfn_pte(). All other modifications should happen in
> > > the actual fault handler that has to deal with such kind of unsharing either
> > > way when modifying the PTE.
> > >
> > > If the pages are already in a COW-ed pagetable in the desired "shared" state
> > > (e.g., PageAnonExclusive cleared on an anonymous page), R/O pinning of such
> > > pages will just work as expected and we shouldn't be surprised by another
> > > set of GUP+COW CVEs.
> > >
> > > We'd really only deduplicate the page table and not play other tricks with
> > > the actual page table content that differ from the existing way of handling
> > > fork().
> > >
> > > I don't immediately see why we need COW_PTE_OWN_EXCLUSIVE in GUP code when
> > > not modifying the page table. I think we only need "we have to unshare this
> > > page table now" in follow_pfn_pte() and inside the fault handling when GUP
> > > triggers a fault.
> > >
> > > I hope my assumption is correct, or am I missing something?
> > >
> >
> > My consideration is when we pinned the page and did the COW to make the
> > page table be shared. It might not allow mapping the pinned page to R/O)
> > into both processes.
> >
> > So, if the fork is working on the shared state, it needs to recover the
> > table and copy to a new one since that pinned page will need to copy
> > immediately. We can hold the shared state after occurring such a
> > situation. So we still need some trick to let the fork() know which page
> > table already has the pinned page (or such page won't let us share)
> > before going to duplicate.
> >
> > Am I wrong here?
>
> I think you might be overthinking this. Let's keep it simple:
>
> 1) Handle pinned anon pages just as I described below, falling back to the
> "slow" path of page table copying.
>
> 2) Once we passed that stage, you can be sure that the COW-ed page table
> cannot have actually pinned anon pages. All anon pages in such a page table
> have PageAnonExclusive cleared and are "maybe shared". GUP cannot succeed in
> pinning these pages anymore, because it will only pin exclusive anon pages!
>
> 3) If anybody wants to take a R/O pin on a shared anon page that is mapped
> into a COW-ed page table, we trigger a fault with FAULT_FLAG_UNSHARE instead
> of pinning the page. This has to break COW on the page table and properly
> map an exclusive anon page into it, breaking COW.
>
> Do you see a problem with that?
>
> >
> > After that, since we handled the accounting in fork(), we don't need
> > ownership (pmd_t pointer) anymore. We have to find another way to mark
> > the table to be exclusive. (Right now, COW_PTE_OWNER_EXCLUSIVE flag is
> > stored at that space.)
> >
> > > >
> > > > > But devil is in the detail (page table lock, TLB flushing).
> > > >
> > > > Sure, it might be an overhead in the page fault and needs to be handled
> > > > carefully. ;)
> > > >
> > > > > "will make fork() even have more overhead" is not a good excuse for such
> > > > > complexity/hacks -- sure, it will make your benchmark results look better in
> > > > > comparison ;)
> > > >
> > > > ;);)
> > > > I think that, even if we do the accounting with the COW page table, it
> > > > still has a little bit improve.
> > >
> > > :)
> > >
> > > My gut feeling is that this is true. While we have to do a pass over the
> > > parent page table during fork and wrprotect all PTEs etc., we don't have to
> > > duplicate the page table content and allocate/free memory for that.
> > >
> > > One interesting case is when we cannot share an anon page with the child
> > > process because it maybe pinned -- and we have to copy it via
> > > copy_present_page(). In that case, the page table between the parent and the
> > > child would differ and we'd not be able to share the page table.
> >
> > That is what I want to say above.
> > The case might happen in the middle of the shared page table progress.
> > It might cost more overhead to recover it. Therefore, if GUP wants to
> > pin the mapped page we can mark the PTE table first, so fork() won't
> > waste time doing the work for sharing.
>
> Having pinned pages is a corner case for most apps. No need to worry about
> optimizing this corner case for now.
>
> I see what you are trying to optimize, but I don't think this is needed in a
> first version, and probably never is needed.
>
>
> Any attempts to mark page tables in a certain way from GUP
> (COW_PTE_OWNER_EXCLUSIVE) is problematic either way: GUP-fast
> (get_user_pages_fast) can race with pretty much anything, even with
> concurrent fork. I suspect your current code might be really racy in that
> regard.
I see.
Now, I know why optimizing that corner case is not worth it.
Thank you for explaining that.
Thanks,
Chih-En Lin
next prev parent reply other threads:[~2022-09-29 18:57 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-27 16:29 [RFC PATCH v2 0/9] Introduce Copy-On-Write to Page Table Chih-En Lin
2022-09-27 16:29 ` [RFC PATCH v2 1/9] mm: Add new mm flags for Copy-On-Write PTE table Chih-En Lin
2022-09-27 17:23 ` Nadav Amit
2022-09-27 17:36 ` Chih-En Lin
2022-09-27 16:29 ` [RFC PATCH v2 2/9] mm: pgtable: Add sysctl to enable COW PTE Chih-En Lin
2022-09-27 17:27 ` Nadav Amit
2022-09-27 18:05 ` Chih-En Lin
2022-09-27 21:22 ` John Hubbard
2022-09-28 8:36 ` Chih-En Lin
2022-09-27 16:29 ` [RFC PATCH v2 3/9] mm, pgtable: Add ownership to PTE table Chih-En Lin
2022-09-27 17:30 ` Nadav Amit
2022-09-27 18:23 ` Chih-En Lin
2022-09-27 16:29 ` [RFC PATCH v2 4/9] mm: Add COW PTE fallback functions Chih-En Lin
2022-09-27 17:51 ` Nadav Amit
2022-09-27 19:00 ` Chih-En Lin
2022-09-27 16:29 ` [RFC PATCH v2 5/9] mm, pgtable: Add a refcount to PTE table Chih-En Lin
2022-09-27 17:59 ` Nadav Amit
2022-09-27 19:07 ` Chih-En Lin
2022-09-27 16:29 ` [RFC PATCH v2 6/9] mm, pgtable: Add COW_PTE_OWNER_EXCLUSIVE flag Chih-En Lin
2022-09-27 16:29 ` [RFC PATCH v2 7/9] mm: Add the break COW PTE handler Chih-En Lin
2022-09-27 18:15 ` Nadav Amit
2022-09-27 19:23 ` Chih-En Lin
2022-09-27 16:29 ` [RFC PATCH v2 8/9] mm: Handle COW PTE with reclaim algorithm Chih-En Lin
2022-09-27 16:29 ` [RFC PATCH v2 9/9] mm: Introduce Copy-On-Write PTE table Chih-En Lin
2022-09-27 18:38 ` Nadav Amit
2022-09-27 19:53 ` Chih-En Lin
2022-09-27 21:26 ` John Hubbard
2022-09-28 8:52 ` Chih-En Lin
2022-09-28 14:03 ` David Hildenbrand
2022-09-29 13:38 ` Chih-En Lin
2022-09-29 13:49 ` Chih-En Lin
2022-09-29 17:24 ` David Hildenbrand
2022-09-29 18:29 ` Chih-En Lin
2022-09-29 18:38 ` David Hildenbrand
2022-09-29 18:57 ` Chih-En Lin [this message]
2022-09-29 19:00 ` David Hildenbrand
2022-09-29 18:40 ` Nadav Amit
2022-09-29 19:02 ` Chih-En Lin
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=YzXqpN5bnG9HSGyI@strix-laptop \
--to=shiyn.lin@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=anshuman.khandual@arm.com \
--cc=arnd@arndb.de \
--cc=bigeasy@linutronix.de \
--cc=christophe.leroy@csgroup.eu \
--cc=david@redhat.com \
--cc=fenghua.yu@intel.com \
--cc=foxhoundsk.tw@gmail.com \
--cc=jserv@ccns.ncku.edu.tw \
--cc=keescook@chromium.org \
--cc=kirill.shutemov@linux.intel.com \
--cc=kunyu@nfschina.com \
--cc=linmiaohe@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=luto@kernel.org \
--cc=mcgrof@kernel.org \
--cc=minchan@kernel.org \
--cc=namit@vmware.com \
--cc=pasha.tatashin@soleen.com \
--cc=peng301@purdue.edu \
--cc=peterx@redhat.com \
--cc=pfonseca@purdue.edu \
--cc=shy828301@gmail.com \
--cc=song@kernel.org \
--cc=surenb@google.com \
--cc=tglx@linutronix.de \
--cc=tongtiangen@huawei.com \
--cc=vbabka@suse.cz \
--cc=william.kucharski@oracle.com \
--cc=willy@infradead.org \
--cc=yzaikin@google.com \
--cc=zhengqi.arch@bytedance.com \
/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