From: Andrea Arcangeli <aarcange@redhat.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Avi Kivity <avi@redhat.com>, Thomas Gleixner <tglx@linutronix.de>,
Rik van Riel <riel@redhat.com>,
linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
Kent Overstreet <kent.overstreet@gmail.com>,
Ingo Molnar <mingo@elte.hu>
Subject: Re: [COUNTERPATCH] mm: avoid overflowing preempt_count() in mmu_take_all_locks()
Date: Thu, 1 Apr 2010 19:04:41 +0200 [thread overview]
Message-ID: <20100401170441.GA5825@random.random> (raw)
In-Reply-To: <1270140592.1598.153.camel@laptop>
On Thu, Apr 01, 2010 at 06:49:52PM +0200, Peter Zijlstra wrote:
> On Thu, 2010-04-01 at 18:45 +0200, Peter Zijlstra wrote:
> > On Thu, 2010-04-01 at 18:18 +0200, Andrea Arcangeli wrote:
> > > On Thu, Apr 01, 2010 at 06:12:34PM +0200, Peter Zijlstra wrote:
> > > > One thing we can do there is to mutex_trylock() if we get the lock, see
> > > > if we've got the right object, if the trylock fails we can do the
> > > > refcount thing and sleep. That would allow the fast-path to remain a
> > > > single atomic.
> > >
> > > But then how do you know which anon_vma_unlink has to decrease the
> > > refcount and which not? That info should need to be stored in the
> > > kernel stack, can't be stored in the vma. I guess it's feasible but
> > > passing that info around sounds more tricky than the trylock itself
> > > (adding params to those functions with int &refcount).
> >
> > I was thinking of something like:
> >
> > struct anon_vma *page_lock_anon_vma(struct page *page)
> > {
> > struct anon_vma *anon_vma = NULL;
> > unsigned long anon_mapping;
> >
> > rcu_read_lock();
> > anon_mapping = (unsigned long) ACCESS_ONCE(page->mapping);
> > if ((anon_mapping & PAGE_MAPPING_FLAGS) != PAGE_MAPPING_ANON)
> > goto out;
> > if (!page_mapped(page))
> > goto out;
> >
> > anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON);
> > if (!mutex_trylock(&anon_vma->lock)) {
> > if (atomic_inc_unless_zero(&anon_vma->ref)) {
> > rcu_read_unlock();
> > mutex_lock(&anon_vma->lock);
> > atomic_dec(&anon_vma->ref); /* ensure the lock pins it */
> > } else
> > anon_vma = NULL;
> > }
> > rcu_read_unlock();
> >
> > return anon_vma;
> > }
> >
> > void page_unlock_anon_vma(struct anon_vma *anon_vma)
> > {
> > mutex_unlock(&anon_vma->lock);
> > }
> >
> > Then anybody reaching ref==0 would only need to sync against the lock
> > before freeing.
>
> Ah, there is a race where the dec after lock makes it 0, we could catch
> that by making it -1 and free in unlock_anon_vma().
You'd simply need to atomic_dec_and_test instead of atomic_dec above,
then you free it there above and return NULL.
The bug is to ever call atomic_dec instead of always
atomic_dec_and_test all over the place. I doubt you could fix it with
a -1.
next prev parent reply other threads:[~2010-04-01 17:05 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-30 17:36 [PATCH] increase PREEMPT_BITS to 12 to avoid overflow when starting KVM Rik van Riel
2010-03-30 17:56 ` Peter Zijlstra
2010-03-30 18:05 ` Rik van Riel
2010-03-30 18:34 ` Peter Zijlstra
2010-04-01 9:40 ` [COUNTERPATCH] mm: avoid overflowing preempt_count() in mmu_take_all_locks() Avi Kivity
2010-04-01 10:31 ` Peter Zijlstra
2010-04-01 11:04 ` Thomas Gleixner
2010-04-01 11:13 ` Avi Kivity
2010-04-01 11:16 ` Peter Zijlstra
2010-04-01 11:19 ` Avi Kivity
2010-04-01 15:36 ` Andrea Arcangeli
2010-04-01 15:39 ` Avi Kivity
2010-04-01 15:54 ` Andrea Arcangeli
2010-04-01 16:02 ` Avi Kivity
2010-04-01 16:12 ` Andrea Arcangeli
2010-04-01 11:17 ` Avi Kivity
2010-04-01 11:27 ` Peter Zijlstra
2010-04-01 11:43 ` Peter Zijlstra
2010-04-01 11:47 ` Avi Kivity
2010-04-01 15:42 ` Andrea Arcangeli
2010-04-01 15:50 ` Peter Zijlstra
2010-04-01 15:56 ` Peter Zijlstra
2010-04-01 16:07 ` Andrea Arcangeli
2010-04-01 16:32 ` Peter Zijlstra
2010-04-01 16:00 ` Andrea Arcangeli
2010-04-01 15:51 ` Avi Kivity
2010-04-01 15:56 ` Peter Zijlstra
2010-04-01 16:06 ` Avi Kivity
2010-04-01 16:15 ` Paul E. McKenney
2010-04-01 16:36 ` Peter Zijlstra
2010-04-01 17:02 ` Paul E. McKenney
2010-04-01 16:08 ` Andrea Arcangeli
2010-04-01 16:14 ` Paul E. McKenney
2010-04-01 16:02 ` Andrea Arcangeli
2010-04-01 16:12 ` Peter Zijlstra
2010-04-01 16:18 ` Andrea Arcangeli
2010-04-01 16:45 ` Peter Zijlstra
2010-04-01 16:49 ` Peter Zijlstra
2010-04-01 17:04 ` Andrea Arcangeli [this message]
2010-04-01 14:16 ` Rik van Riel
2010-04-01 15:32 ` Andrea Arcangeli
2010-04-01 15:37 ` Avi Kivity
2010-04-01 11:09 ` Avi Kivity
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=20100401170441.GA5825@random.random \
--to=aarcange@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=avi@redhat.com \
--cc=kent.overstreet@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=peterz@infradead.org \
--cc=riel@redhat.com \
--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;
as well as URLs for NNTP newsgroup(s).