Linux-Fsdevel Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Matthew Wilcox <willy@infradead.org>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: linux-fsdevel@vger.kernel.org,
	fuse-devel <fuse-devel@lists.sourceforge.net>,
	linux-mm <linux-mm@kvack.org>, miklos <mszeredi@redhat.com>,
	"Gabriel Krisman Bertazi" <krisman@collabora.com>,
	"André Almeida" <andrealmeid@collabora.com>
Subject: Re: [fuse-devel] fuse: trying to steal weird page
Date: Mon, 18 May 2020 07:48:53 -0700	[thread overview]
Message-ID: <20200518144853.GT16070@bombadil.infradead.org> (raw)
In-Reply-To: <CAJfpegseoCE_mVGPR5Bt8S1WZ2bi2DnUb7QqgPm=okzx_wT31A@mail.gmail.com>

On Mon, May 18, 2020 at 02:45:02PM +0200, Miklos Szeredi wrote:
> On Sun, May 3, 2020 at 12:27 PM Matthew Wilcox <willy@infradead.org> wrote:
> >
> > On Sun, May 03, 2020 at 09:43:41AM +0100, Nikolaus Rath wrote:
> > > Here's what I got:
> > >
> > > [  221.277260] page:ffffec4bbd639880 refcount:1 mapcount:0 mapping:0000000000000000 index:0xd9
> > > [  221.277265] flags: 0x17ffffc0000097(locked|waiters|referenced|uptodate|lru)
> > > [  221.277269] raw: 0017ffffc0000097 ffffec4bbd62f048 ffffec4bbd619308 0000000000000000
> > > [  221.277271] raw: 00000000000000d9 0000000000000000 00000001ffffffff ffff9aec11beb000
> > > [  221.277272] page dumped because: fuse: trying to steal weird page
> > > [  221.277273] page->mem_cgroup:ffff9aec11beb000
> >
> > Great!  Here's the condition:
> >
> >         if (page_mapcount(page) ||
> >             page->mapping != NULL ||
> >             page_count(page) != 1 ||
> >             (page->flags & PAGE_FLAGS_CHECK_AT_PREP &
> >              ~(1 << PG_locked |
> >                1 << PG_referenced |
> >                1 << PG_uptodate |
> >                1 << PG_lru |
> >                1 << PG_active |
> >                1 << PG_reclaim))) {
> >
> > mapcount is 0, mapping is NULL, refcount is 1, so that's all fine.
> > flags has 'waiters' set, which is not in the allowed list.  I don't
> > know the internals of FUSE, so I don't know why that is.
> >
> > Also, page_count() is unstable.  Unless there has been an RCU grace period
> > between when the page was freed and now, a speculative reference may exist
> > from the page cache.  So I would say this is a bad thing to check for.
> 
> page_cache_pipe_buf_steal() calls remove_mapping() which calls
> page_ref_unfreeze(page, 1).  That sets the refcount to 1, right?
> 
> What am I missing?

find_get_entry() calling page_cache_get_speculative().

In a previous allocation, this page belonged to the page cache.  Then it
was freed, but another thread is in the middle of a page cache lookup and
has already loaded the pointer.  It is now delayed by a few clock ticks.

Now the page is allocated to FUSE, which calls page_ref_unfreeze().
And then the refcount gets bumped to 2 by page_cache_get_speculative().
find_get_entry() calls xas_reload() and discovers this page is no longer
at that index, so it calls put_page(), but in that narrow window, FUSE
checks the refcount and finds it's not 1.

Monumentally unlikely, of course, so you've probably never seen it,
but multiply by the hundreds of millions of devices running Linux,
and somebody will hit it someday.

  reply	other threads:[~2020-05-18 14:48 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-02 19:09 Nikolaus Rath
2020-05-02 19:52 ` Nikolaus Rath
2020-05-03  3:26   ` Matthew Wilcox
2020-05-03  8:43     ` [fuse-devel] " Nikolaus Rath
2020-05-03 10:27       ` Matthew Wilcox
2020-05-03 18:28         ` Gabriel Krisman Bertazi
2020-05-03 20:06           ` Matthew Wilcox
2020-05-03 20:25           ` Nikolaus Rath
2020-05-06 13:57             ` Vlastimil Babka
2020-05-03 21:34         ` Hugh Dickins
2020-05-18 12:45         ` Miklos Szeredi
2020-05-18 14:48           ` Matthew Wilcox [this message]
2020-05-18 14:58             ` Miklos Szeredi
2020-05-18 15:26               ` Matthew Wilcox
  -- strict thread matches above, loose matches on Subject: below --
2018-12-26 21:43 Nikolaus Rath
2019-01-07  8:28 ` [fuse-devel] " Miklos Szeredi
2019-01-07 21:05   ` Nikolaus Rath
2019-01-08  8:27     ` Miklos Szeredi
2019-01-08 10:35       ` Nikolaus Rath
2019-01-09  8:07         ` Miklos Szeredi
2019-01-11 15:39           ` Nikolaus Rath
2019-01-11 15:39             ` [fuse-devel] " Nikolaus Rath
2019-02-10 22:05             ` Nikolaus Rath
2019-02-12 14:57               ` Miklos Szeredi
2019-02-12 21:28                 ` Nikolaus Rath
2019-02-25 21:41                   ` Nikolaus Rath
2019-02-26 12:57                     ` Miklos Szeredi
2019-02-26 13:30                       ` Miklos Szeredi

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=20200518144853.GT16070@bombadil.infradead.org \
    --to=willy@infradead.org \
    --cc=andrealmeid@collabora.com \
    --cc=fuse-devel@lists.sourceforge.net \
    --cc=krisman@collabora.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=miklos@szeredi.hu \
    --cc=mszeredi@redhat.com \
    --subject='Re: [fuse-devel] fuse: trying to steal weird page' \
    /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

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).