From: Matthew Wilcox <willy@linux.intel.com>
To: linux-kernel@vger.kernel.org,
Konstantin Khlebnikov <khlebnikov@openvz.org>,
Hugh Dickins <hughd@google.com>,
Andrew Morton <akpm@linux-foundation.org>
Subject: Bug in radix tree gang lookup?
Date: Fri, 22 Jan 2016 08:40:12 -0500 [thread overview]
Message-ID: <20160122134012.GC2948@linux.intel.com> (raw)
I think there's a race in radix_tree_gang_lookup() (and
related functions). I was trying to understand why we need the
'indirect_to_ptr()' call here:
radix_tree_for_each_slot(slot, root, &iter, first_index) {
results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot));
if (!results[ret])
continue;
if (++ret == max_items)
break;
}
The slots returned are supposed to be leaf nodes, so why would they ever
have the indirect bit set?
The only two cases I can think of where we'd see a slot with the indirect
bit set is if we're calling radix_tree_gang_lookup() under the RCU read
lock and simultaneously growing / shrinking the tree. When the tree
transitions from height 0 to height 1, the 'slot' that was returned is now
an internal pointer, so simply knocking off the 'indirect_to_ptr()' bit
is the wrong thing to do; instead of returning a struct page pointer, we
return a pointer to a radix_tree_node, which isn't good. When shrinking
the tree from height 1 to height 0, we may end up looking at a pointer
in to-be-freed memory, but it's still a valid pointer to a struct page,
so I think we're OK in the shrink case.
The lockless page cache shows how to handle this correctly; when we
see an indirect bit come back in a slot, we should retry the lookup.
I think that's the right thing to do in this case, but I'd like someone
to check my reasoning before I propose a patch.
next reply other threads:[~2016-01-22 13:40 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-22 13:40 Matthew Wilcox [this message]
2016-01-27 4:04 ` Bug in radix tree gang lookup? 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=20160122134012.GC2948@linux.intel.com \
--to=willy@linux.intel.com \
--cc=akpm@linux-foundation.org \
--cc=hughd@google.com \
--cc=khlebnikov@openvz.org \
--cc=linux-kernel@vger.kernel.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 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.