From: Hugh Dickins <hugh.dickins@tiscali.co.uk>
To: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
Nick Piggin <npiggin@suse.de>, Ingo Molnar <mingo@elte.hu>,
LKML <linux-kernel@vger.kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
Darren Hart <dvhltc@us.ibm.com>,
Ulrich Drepper <drepper@gmail.com>
Subject: Re: [PATCH] futex: Fix ZERO_PAGE cause infinite loop
Date: Wed, 30 Dec 2009 16:03:37 +0000 (GMT) [thread overview]
Message-ID: <alpine.LSU.2.00.0912301437420.3369@sister.anvils> (raw)
In-Reply-To: <20091225083305.AA78.A69D9226@jp.fujitsu.com>
This was a good find, thanks a lot for discovering it.
I'm afraid I'd quite forgotten all the mm-implementation-dependence
that has accumulated (for good performance reasons) in kernel/futex.c.
(Luckily, given that KSM pages are also PageAnon, it will happen to
be working correctly on them: that's not your concern, but something
your report has reminded me to consider.)
On Fri, 25 Dec 2009, KOSAKI Motohiro wrote:
> > > diff --git a/kernel/futex.c b/kernel/futex.c
> > > index 8e3c3ff..79b89cc 100644
> > > --- a/kernel/futex.c
> > > +++ b/kernel/futex.c
> > > @@ -254,6 +254,8 @@ again:
> > >
> > > page = compound_head(page);
> > > lock_page(page);
> > > + if (is_zero_pfn(page_to_pfn(page)))
> > > + goto anon_key;
If something like this or your replacment does go forward,
then I think that test is better inside the "if (!page->mapping)"
below. Admittedly that adds even more mm-dependence here (relying
on a zero page to have NULL page->mapping); but isn't page_to_pfn()
one of those functions which is trivial on many configs but expensive
on some? Better call it only in the rare case that it's needed.
Though wouldn't it be even better not to use is_zero_pfn() at all?
That was convenient in mm/memory.c because it had the pfn or pte right
at hand, but here a traditional (page == ZERO_PAGE(address)) would be
more efficient.
Which would save having to move is_zero_pfn() from mm/memory.c
to include/linux/mm.h - I'd prefer to keep it private if we can.
But for completeness, this would involve resurrecting the 2.6.19
MIPS move_pte(), which makes sure mremap() move doesn't interfere
with our assumptions. Something like
#define __HAVE_ARCH_MOVE_PTE
pte_t move_pte(pte_t pte, pgprot_t prot, unsigned long old_addr,
unsigned long new_addr)
{
if (pte_present(pte) && is_zero_pfn(pte_pfn(pte)))
pte = mk_pte(ZERO_PAGE(new_addr), prot);
return pte;
}
in arch/mips/include/asm/pgtable.h.
> > > if (!page->mapping) {
> > > unlock_page(page);
> > > put_page(page);
> > > @@ -268,6 +270,7 @@ again:
> > > * the object not the particular process.
> > > */
> > > if (PageAnon(page)) {
> > > + anon_key:
> > > key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */
> > > key->private.mm = mm;
> > > key->private.address = address;
> >
> > Doesn't it make more sense to simply fail the futex op?
If we were to decide to fail the futex op on an unmodified ZERO_PAGE,
couldn't we simply delete the "again" label and just say
if (!page->mapping) {
/* Truncated file page, or a ZERO_PAGE */
unlock_page(page);
put_page(page);
return -EFAULT;
}
I don't know what the retry on that case was expected to achieve.
> >
> > What I mean is, all (?) futex ops assume userspace actually wrote
> > something to the address in question to begin with, therefore it can
> > never be the zero page.
> >
> > So it being the zero page means someone goofed up, and we should bail,
> > no?
I share Peter's wish to avoid cluttering this up with more special
case testing, but also your and Ulrich's wish to keep generality.
>
> Hm. probably we need to discuss more.
>
> Firstly, if we assume current glibc implimentation, you are right,
> we can assume userland always initialize the page explicitly before using
> futex. then we never seen zero page in futex.
>
> but, I don't think futex itself assume it now. at least man page
> doesn't describe such limilation. so, if you prefer bail and man fix,
> I'm acceptable maybe.
Here's another worry with the current futex implementation,
which might help me to decide which way to jump on the ZERO_PAGE.
Originally, a futex on a MAP_PRIVATE (!VM_MAYSHARE) area was necessarily
FUT_OFF_MMSHARED. Nowadays, with the get_user_pages_fast implementation,
we have no idea whether the vma is VM_MAYSHARE or not. So if a futex is
placed in a private area backed by a file, then it could be regarded as
FUT_OFF_INODE at futex_wait() time, but FUT_OFF_MMSHARED at futex_wake()
time.
Perhaps that's no problem at all, it's a long time since I was involved
with futexes, I think you and Peter will grasp the consequences quicker
than I shall.
But it seems no more improbable than the ZERO_PAGE case: some app
might place its futexes in the .data section of the executable,
which is a private mapping of the executable file.
If this case is also an issue, then perhaps we just need to update
the man page to say that whatever is responsible for initializing a
futex does need to write to it (or the page it's in) before it's used,
otherwise behaviour is undefined. (But we should then use the -EFAULT
patch above, we'd all prefer an error to busylooping.)
>
> I don't know any library except glibc use futex directly, or not.
> but we don't have any reason to assume futex is used only glibc.
> (plus, glibc might change its implementation in future release, perhaps)
I expect there are other implementations; but apparently none
that have yet reported this ZERO_PAGE behaviour as a problem.
...
>
> man page fix has another difficulty. in past days, zero pages was perfectly
> transparent from userland. then any man page don't describe "what's zero page".
> then some administrator don't know about zero page at all.
>
> So, if your main disliked point is goto statement, following patch is ok
> to me.
Although I'm as indecisive as Hamlet,
"goto or no goto, that is NOT the question":
I don't care, I think the goto in your original was fine.
>
> Finally, I agree this is really corner case issue. I can agree man page fix
> too. but I hope to know which point you dislike in my patch.
I just prefer not to have to add extra tests for the ZERO_PAGE
if we can get away without them.
Hugh
next prev parent reply other threads:[~2009-12-30 16:03 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-24 9:29 KOSAKI Motohiro
2009-12-24 9:39 ` Peter Zijlstra
2009-12-24 17:15 ` Ulrich Drepper
2009-12-25 1:51 ` KOSAKI Motohiro
2009-12-30 16:03 ` Hugh Dickins [this message]
2010-01-05 7:32 ` [PATCH v2] futex: remove rw parameter from get_futex_key() KOSAKI Motohiro
2010-01-05 11:21 ` Hugh Dickins
2010-01-05 20:41 ` Darren Hart
2010-01-06 2:27 ` KOSAKI Motohiro
2010-01-06 23:14 ` Darren Hart
2010-01-06 23:29 ` Darren Hart
2010-01-13 10:30 ` [tip:core/urgent] futexes: Remove " tip-bot for KOSAKI Motohiro
2010-01-07 6:32 ` [PATCH] mips,mm: Reinstate move_pte optimization KOSAKI Motohiro
2010-01-11 10:15 ` Ralf Baechle
2010-01-05 18:04 ` [PATCH] futex: Fix ZERO_PAGE cause infinite loop Darren Hart
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=alpine.LSU.2.00.0912301437420.3369@sister.anvils \
--to=hugh.dickins@tiscali.co.uk \
--cc=drepper@gmail.com \
--cc=dvhltc@us.ibm.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=kosaki.motohiro@jp.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=npiggin@suse.de \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
/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®