From: Andrew Morton <akpm@zip.com.au>
To: Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
Cc: Rik van Riel <riel@conectiva.com.br>,
linux-kernel@vger.kernel.org, Thomas Molina <tmolina@cox.net>
Subject: Re: Race in pagevec code
Date: Wed, 21 Aug 2002 15:52:35 -0700 [thread overview]
Message-ID: <3D6419B3.50356B8E@zip.com.au> (raw)
In-Reply-To: 20020821222333.21552.qmail@thales.mathematik.uni-ulm.de
Christian Ehrhardt wrote:
>
> On Wed, Aug 21, 2002 at 10:41:48AM -0700, Andrew Morton wrote:
> > Christian Ehrhardt wrote:
> > >
> > > ...
> > > Both processors succeeded in bringing the page_count to zero,
> > > i.e. both processors will add the page to their own
> > > pages_to_free_list.
> >
> > This is why __pagevec_release() has the refcount check inside the lock.
> > If someone else grabbed a ref to the page (also inside the lock) via
> > the LRU, __pagevec_release doesn't free it.
>
> I saw this check but this doesn't help. There is no guarantee that this
> other reference that someone grabbed is still beeing held at the time
> where we do the check:
> The problem is if this newly grabbed reference is again dropped BEFORE
> the check for page_count == 0 but AFTER put_page_test_zero. In this
> case there can be TWO execution paths the BOTH think that they dropped
> the last reference, i.e. both call __free_pages_ok for the same page.
> See?
shrink_cache() detects that, inside the lock, and puts the page back
if it has a zero refcount.
refill_inactive doesn't need to do that, because it calls page_cache_release(),
which should look like this:
void __page_cache_release(struct page *page)
{
unsigned long flags;
spin_lock_irqsave(&_pagemap_lru_lock, flags);
if (TestClearPageLRU(page)) {
if (PageActive(page))
del_page_from_active_list(page);
else
del_page_from_inactive_list(page);
}
if (page_count(page) != 0)
page = NULL;
spin_unlock_irqrestore(&_pagemap_lru_lock, flags);
if (page)
__free_pages_ok(page, 0);
}
If the page count and non-LRUness are both seen inside the lock,
the page is freeable.
We do a similar thing with inodes, via atomic_dec_and_lock.
Despite the transformations, it's based on the 2.4 approach. But you've
successfully worried me, and I'm not really sure it's right, and I'm
dead sure it's too hairy. Something simpler-but-not-sucky is needed.
prev parent reply other threads:[~2002-08-21 22:50 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-08-21 15:45 Race in pagevec code Christian Ehrhardt
2002-08-21 17:41 ` Andrew Morton
2002-08-21 20:27 ` Rik van Riel
2002-08-21 22:23 ` Christian Ehrhardt
2002-08-21 22:52 ` Andrew Morton [this message]
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=3D6419B3.50356B8E@zip.com.au \
--to=akpm@zip.com.au \
--cc=ehrhardt@mathematik.uni-ulm.de \
--cc=linux-kernel@vger.kernel.org \
--cc=riel@conectiva.com.br \
--cc=tmolina@cox.net \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.