From: Hugh Dickins <hugh@veritas.com>
To: James Bottomley <James.Bottomley@SteelEye.com>
Cc: Andrew Morton <akpm@osdl.org>,
parisc-linux@parisc-linux.org, linux-kernel@vger.kernel.org,
Matthew Wilcox <matthew@wil.cx>
Subject: Re: [parisc-linux] Re: [PATCH 3/9] mm: parisc pte atomicity
Date: Mon, 24 Oct 2005 05:36:35 +0100 (BST) [thread overview]
Message-ID: <Pine.LNX.4.61.0510240441570.22402@goblin.wat.veritas.com> (raw)
In-Reply-To: <1130079931.3437.21.camel@mulgrave>
On Sun, 23 Oct 2005, James Bottomley wrote:
> On Sun, 2005-10-23 at 10:02 +0100, Hugh Dickins wrote:
>
> The change does slightly worry me in that it alters the behaviour of
> flush_cache_page() because now it checks the pfn whereas previously it
> didn't. This means that previously we would flush the COW'd page of a
> shared mapping, now we won't.
Perhaps you're thinking of some use of flush_cache_page that no longer
exists in the tree? All the uses I see are passing in the right pfn,
and the question is why translation_exists even gets called by it.
Even those uses of flush_cache_page in asm-parisc/cacheflush.h itself
(which I'd missed before): copy_to_user_page and copy_from_user_page
are only used by nothing but access_process_vm, after get_user_pages:
so any COW has already been done, and the right pfn is passed in.
> > I'm right, aren't I? that the previous pte_none test was actually letting
> > through swap entries and pte_file entries which might look as if they had
> > the right pfn, just by coincidence of their offsets? So flush_dcache_page
> > would stop, thinking it had done a good flush, when actually it hadn't.
>
> Actually, no, pte_none() on parisc is either pte is zero or _PAGE_FLUSH
> (which is our private flag saying we're preserving the pte entry for the
> purposes of flushing even though it's gone) is set.
Sorry, "pte_none test" was my lazy shorthand for the actual test:
if(pte_none(*pte) && ((pte_val(*pte) & _PAGE_FLUSH) == 0))
return NULL;
from which point on it assumes the pte is valid. I'm contending that
a swap entry or pte_file entry does not return NULL there, so is then
treated as a valid pte: and pte_pfn on it might match the target pfn.
I believe my
/* Filter out coincidental file entries and swap entries */
if (!(pte_val(pte) & (_PAGE_FLUSH|_PAGE_PRESENT)))
return 0;
is correct, and avoids that problem (plus avoiding the complication
of parisc's unintuitive pte_none).
> However, now that I
> look at it, are you thinking our ptep_get_and_clear() should be doing a
> check for _PAGE_PRESENT before it sets _PAGE_FLUSH?
That's certainly not what I was thinking. No, I'm pretty sure that
ptep_get_and_clear only gets called when we've got the right lock and
know the pte is present: I don't think you need to make any change there.
(The "pretty sure" reflecting that there's a bit of a macro maze here now,
so actually following up each reference would take a bit longer.)
But you may be seeing something I don't see: I've only just met your
_PAGE_FLUSH, and that unusual pte_none might be letting something
through that I'm overlooking, that you're aware of.
> > But races remain: the pte good at the moment translation_exists checks it,
> > may have been taken out by kswapd a moment later (flush_dcache_mmap_lock
> > only secures the vma_prio_tree structure, not ptes within the vmas);
> > or it may have been COWed in the interval; or zapped from the mm.
> >
> > Can you get a success code out of __flush_cache_page? Or perhaps you
> > should run translation_exists a second time after the __flush_cache_page,
> > to check nothing changed (the pte pointer would then be helpful, to save
> > descending a second time)? Or perhaps it all works out, that any such
> > change which might occur, itself does the __flush_cache_page you need?
>
> Yes, I know ... I never liked the volatility of this, but it's better
> than what was there before, believe me (previously we just flushed the
> first entry we found regardless).
I do believe you!
> Getting a return code out of __flush_dcache_page() is hard because it
> doesn't know if the tlb miss handler nullified the instructions it's
> trying to execute; and they're interruption handlers (meaning we don't
> push anything on the stack for them, they run in shadow registers), so
> getting a return code out of them is next to impossible.
Right, it was just a thought.
> For the flush to be effective in the VIPT cache, we have to have a
> virtual address with a valid translation that points to the correct
> physical address. I suppose we could flush through the tmpalias space
> instead. That's where we set up an artifical translation that's not the
> actual vaddr but instead is congruent to the vaddr so the mapping is
> effective in cache aliasing terms. Our congruence boundary is 4MB, so
> we set up a private (per cpu) 4MB space (tmpalias) where we can set up
> our pte's (or actually manufacture them in the tlb miss handler)
> securely.
I have no appreciation at all how that would compare. On the one hand
it sounds like a lot of overhead you'd understandably prefer to avoid;
on the other hand, this hit-and-miss search of the vma_prio_tree might
be a worse overhead better avoided. I've no appreciation at all.
But I made two suggestions above that might be less work. One,
requiring no work but research, that _perhaps_ in all the racy cases
you can rely on the __flush_cache_page having been done by the racer?
I can't tell, and it may be obvious to you that that's a non-starter.
Other, that you just check the pte again after the __flush_cache_page,
if it's no longer right then assume the flush didn't work and continue.
There is a small chance that the pte was right before, wrong during the
flush, then right after (something else faulted it back in, while we
were away... I was about to say handling an interrupt, but actually
even interrupts are disabled here by flush_dcache_mmap_lock, since
that's a reuse of mapping->tree_lock). But it would improve the
safety by several orders of magnitude.
Hugh
next prev parent reply other threads:[~2005-10-24 4:37 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-10-22 16:18 [PATCH 0/9] mm: page fault scalability Hugh Dickins
2005-10-22 16:19 ` [PATCH 1/9] mm: i386 sh sh64 ready for split ptlock Hugh Dickins
2005-10-22 18:24 ` Paul Mundt
2005-10-22 16:22 ` [PATCH 2/9] mm: arm " Hugh Dickins
2005-10-22 17:02 ` Russell King
2005-10-23 8:27 ` Hugh Dickins
2005-10-25 2:45 ` Nicolas Pitre
2005-10-25 6:31 ` Hugh Dickins
2005-10-25 14:55 ` Nicolas Pitre
2005-10-25 7:55 ` Russell King
2005-10-25 15:00 ` Nicolas Pitre
2005-10-26 0:20 ` Russell King
2005-10-26 1:26 ` Nicolas Pitre
2005-10-31 22:19 ` Jesper Juhl
2005-10-31 22:27 ` Russell King
2005-10-31 22:34 ` Jesper Juhl
2005-10-31 22:50 ` Russell King
2005-10-22 16:23 ` [PATCH 3/9] mm: parisc pte atomicity Hugh Dickins
2005-10-22 16:33 ` Matthew Wilcox
2005-10-22 17:08 ` [parisc-linux] " James Bottomley
2005-10-23 9:02 ` Hugh Dickins
2005-10-23 15:05 ` James Bottomley
2005-10-24 4:36 ` Hugh Dickins [this message]
2005-10-24 14:56 ` James Bottomley
2005-10-24 16:49 ` Hugh Dickins
2005-10-22 16:24 ` [PATCH 4/9] mm: cris v32 mmu_context_lock Hugh Dickins
2005-10-22 16:25 ` [PATCH 5/9] mm: uml pte atomicity Hugh Dickins
2005-10-22 16:27 ` [PATCH 6/9] mm: uml kill unused Hugh Dickins
2005-10-22 19:23 ` Jeff Dike
2005-10-22 16:29 ` [PATCH 7/9] mm: split page table lock Hugh Dickins
2005-10-23 16:54 ` Nikita Danilov
2005-10-23 21:27 ` Andrew Morton
2005-10-23 22:22 ` Andrew Morton
2005-10-24 3:38 ` Hugh Dickins
2005-10-24 4:16 ` Andrew Morton
2005-10-24 4:58 ` Hugh Dickins
2005-10-24 3:09 ` Hugh Dickins
2005-10-23 21:49 ` Andrew Morton
2005-10-24 3:12 ` Hugh Dickins
2005-10-22 16:30 ` [PATCH 8/9] mm: fix rss and mmlist locking Hugh Dickins
2005-10-22 16:31 ` [PATCH 9/9] mm: update comments to pte lock Hugh Dickins
2005-10-23 7:49 ` [PATCH 6/9 take 2] mm: uml kill unused Hugh Dickins
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=Pine.LNX.4.61.0510240441570.22402@goblin.wat.veritas.com \
--to=hugh@veritas.com \
--cc=James.Bottomley@SteelEye.com \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=matthew@wil.cx \
--cc=parisc-linux@parisc-linux.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
all inboxes | Powered by JetHome®