From: zhong jiang <zhongjiang@huawei.com>
To: Matthew Wilcox <matthew.r.wilcox@intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Hugh Dickins <hughd@google.com>, Ohad Ben-Cohen <ohad@wizery.com>,
Matthew Wilcox <willy@linux.intel.com>,
Konstantin Khlebnikov <khlebnikov@openvz.org>,
<linux-kernel@vger.kernel.org>, <linux-fsdevel@vger.kernel.org>,
<linux-mm@kvack.org>, <stable@vger.kernel.org>
Subject: Re: [PATCH 1/5] radix-tree: Fix race in gang lookup
Date: Fri, 4 Mar 2016 21:21:33 +0800 [thread overview]
Message-ID: <56D98BDD.3060806@huawei.com> (raw)
In-Reply-To: <1453929472-25566-2-git-send-email-matthew.r.wilcox@intel.com>
On 2016/1/28 5:17, Matthew Wilcox wrote:
> From: Matthew Wilcox <willy@linux.intel.com>
>
> If the indirect_ptr bit is set on a slot, that indicates we need to
> redo the lookup. Introduce a new function radix_tree_iter_retry()
> which forces the loop to retry the lookup by setting 'slot' to NULL and
> turning the iterator back to point at the problematic entry.
>
> This is a pretty rare problem to hit at the moment; the lookup has to
> race with a grow of the radix tree from a height of 0. The consequences
> of hitting this race are that gang lookup could return a pointer to a
> radix_tree_node instead of a pointer to whatever the user had inserted
> in the tree.
>
> Fixes: cebbd29e1c2f ("radix-tree: rewrite gang lookup using iterator")
> Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
> Cc: stable@vger.kernel.org
> ---
> include/linux/radix-tree.h | 16 ++++++++++++++++
> lib/radix-tree.c | 12 ++++++++++--
> 2 files changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
> index f9a3da5bf892..db0ed595749b 100644
> --- a/include/linux/radix-tree.h
> +++ b/include/linux/radix-tree.h
> @@ -387,6 +387,22 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
> struct radix_tree_iter *iter, unsigned flags);
>
> /**
> + * radix_tree_iter_retry - retry this chunk of the iteration
> + * @iter: iterator state
> + *
> + * If we iterate over a tree protected only by the RCU lock, a race
> + * against deletion or creation may result in seeing a slot for which
> + * radix_tree_deref_retry() returns true. If so, call this function
> + * and continue the iteration.
> + */
> +static inline __must_check
> +void **radix_tree_iter_retry(struct radix_tree_iter *iter)
> +{
> + iter->next_index = iter->index;
> + return NULL;
> +}
> +
> +/**
> * radix_tree_chunk_size - get current chunk size
> *
> * @iter: pointer to radix tree iterator
> diff --git a/lib/radix-tree.c b/lib/radix-tree.c
> index a25f635dcc56..65422ac17114 100644
> --- a/lib/radix-tree.c
> +++ b/lib/radix-tree.c
> @@ -1105,9 +1105,13 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
> return 0;
>
> radix_tree_for_each_slot(slot, root, &iter, first_index) {
> - results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot));
> + results[ret] = rcu_dereference_raw(*slot);
> if (!results[ret])
> continue;
> + if (radix_tree_is_indirect_ptr(results[ret])) {
> + slot = radix_tree_iter_retry(&iter);
> + continue;
> + }
> if (++ret == max_items)
> break;
> }
according to your patch, after A race occur, slot equals to null. radix_tree_next_slot() will continue
to work. Therefore, it will not return the problematic entry.
> @@ -1184,9 +1188,13 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
> return 0;
>
> radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) {
> - results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot));
> + results[ret] = rcu_dereference_raw(*slot);
> if (!results[ret])
> continue;
> + if (radix_tree_is_indirect_ptr(results[ret])) {
> + slot = radix_tree_iter_retry(&iter);
> + continue;
> + }
> if (++ret == max_items)
> break;
> }
WARNING: multiple messages have this Message-ID (diff)
From: zhong jiang <zhongjiang@huawei.com>
To: Matthew Wilcox <matthew.r.wilcox@intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Hugh Dickins <hughd@google.com>, Ohad Ben-Cohen <ohad@wizery.com>,
Matthew Wilcox <willy@linux.intel.com>,
Konstantin Khlebnikov <khlebnikov@openvz.org>,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-mm@kvack.org, stable@vger.kernel.org
Subject: Re: [PATCH 1/5] radix-tree: Fix race in gang lookup
Date: Fri, 4 Mar 2016 21:21:33 +0800 [thread overview]
Message-ID: <56D98BDD.3060806@huawei.com> (raw)
In-Reply-To: <1453929472-25566-2-git-send-email-matthew.r.wilcox@intel.com>
On 2016/1/28 5:17, Matthew Wilcox wrote:
> From: Matthew Wilcox <willy@linux.intel.com>
>
> If the indirect_ptr bit is set on a slot, that indicates we need to
> redo the lookup. Introduce a new function radix_tree_iter_retry()
> which forces the loop to retry the lookup by setting 'slot' to NULL and
> turning the iterator back to point at the problematic entry.
>
> This is a pretty rare problem to hit at the moment; the lookup has to
> race with a grow of the radix tree from a height of 0. The consequences
> of hitting this race are that gang lookup could return a pointer to a
> radix_tree_node instead of a pointer to whatever the user had inserted
> in the tree.
>
> Fixes: cebbd29e1c2f ("radix-tree: rewrite gang lookup using iterator")
> Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
> Cc: stable@vger.kernel.org
> ---
> include/linux/radix-tree.h | 16 ++++++++++++++++
> lib/radix-tree.c | 12 ++++++++++--
> 2 files changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
> index f9a3da5bf892..db0ed595749b 100644
> --- a/include/linux/radix-tree.h
> +++ b/include/linux/radix-tree.h
> @@ -387,6 +387,22 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
> struct radix_tree_iter *iter, unsigned flags);
>
> /**
> + * radix_tree_iter_retry - retry this chunk of the iteration
> + * @iter: iterator state
> + *
> + * If we iterate over a tree protected only by the RCU lock, a race
> + * against deletion or creation may result in seeing a slot for which
> + * radix_tree_deref_retry() returns true. If so, call this function
> + * and continue the iteration.
> + */
> +static inline __must_check
> +void **radix_tree_iter_retry(struct radix_tree_iter *iter)
> +{
> + iter->next_index = iter->index;
> + return NULL;
> +}
> +
> +/**
> * radix_tree_chunk_size - get current chunk size
> *
> * @iter: pointer to radix tree iterator
> diff --git a/lib/radix-tree.c b/lib/radix-tree.c
> index a25f635dcc56..65422ac17114 100644
> --- a/lib/radix-tree.c
> +++ b/lib/radix-tree.c
> @@ -1105,9 +1105,13 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
> return 0;
>
> radix_tree_for_each_slot(slot, root, &iter, first_index) {
> - results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot));
> + results[ret] = rcu_dereference_raw(*slot);
> if (!results[ret])
> continue;
> + if (radix_tree_is_indirect_ptr(results[ret])) {
> + slot = radix_tree_iter_retry(&iter);
> + continue;
> + }
> if (++ret == max_items)
> break;
> }
according to your patch, after A race occur, slot equals to null. radix_tree_next_slot() will continue
to work. Therefore, it will not return the problematic entry.
> @@ -1184,9 +1188,13 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
> return 0;
>
> radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) {
> - results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot));
> + results[ret] = rcu_dereference_raw(*slot);
> if (!results[ret])
> continue;
> + if (radix_tree_is_indirect_ptr(results[ret])) {
> + slot = radix_tree_iter_retry(&iter);
> + continue;
> + }
> if (++ret == max_items)
> break;
> }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2016-03-04 13:21 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-27 21:17 [PATCH 0/5] Fix races & improve the radix tree iterator patterns Matthew Wilcox
2016-01-27 21:17 ` Matthew Wilcox
2016-01-27 21:17 ` [PATCH 1/5] radix-tree: Fix race in gang lookup Matthew Wilcox
2016-01-27 21:17 ` Matthew Wilcox
2016-02-03 21:37 ` Konstantin Khlebnikov
2016-02-03 21:37 ` Konstantin Khlebnikov
2016-02-04 8:44 ` Konstantin Khlebnikov
2016-03-04 13:21 ` zhong jiang [this message]
2016-03-04 13:21 ` zhong jiang
2016-01-27 21:17 ` [PATCH 2/5] hwspinlock: Fix race between radix tree insertion and lookup Matthew Wilcox
2016-01-27 21:17 ` Matthew Wilcox
2016-01-27 21:17 ` [PATCH 3/5] btrfs: Use radix_tree_iter_retry() Matthew Wilcox
2016-01-27 21:17 ` Matthew Wilcox
2016-02-01 14:34 ` David Sterba
2016-02-01 14:34 ` David Sterba
2016-01-27 21:17 ` [PATCH 4/5] mm: " Matthew Wilcox
2016-01-27 21:17 ` Matthew Wilcox
2016-01-29 14:45 ` Vlastimil Babka
2016-01-29 14:45 ` Vlastimil Babka
2016-01-29 14:45 ` Vlastimil Babka
2016-01-29 14:50 ` Matthew Wilcox
2016-01-29 14:50 ` Matthew Wilcox
2016-02-19 18:02 ` Sasha Levin
2016-02-19 18:02 ` Sasha Levin
2016-01-27 21:17 ` [PATCH 5/5] radix-tree,shmem: Introduce radix_tree_iter_next() Matthew Wilcox
2016-01-27 21:17 ` Matthew Wilcox
2016-02-04 8:50 ` Konstantin Khlebnikov
2016-02-04 8:50 ` Konstantin Khlebnikov
2016-01-28 7:17 ` [PATCH 0/5] Fix races & improve the radix tree iterator patterns Konstantin Khlebnikov
2016-01-28 7:17 ` Konstantin Khlebnikov
2016-02-03 6:27 ` Konstantin Khlebnikov
2016-02-03 6:27 ` Konstantin Khlebnikov
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=56D98BDD.3060806@huawei.com \
--to=zhongjiang@huawei.com \
--cc=akpm@linux-foundation.org \
--cc=hughd@google.com \
--cc=khlebnikov@openvz.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=matthew.r.wilcox@intel.com \
--cc=ohad@wizery.com \
--cc=stable@vger.kernel.org \
--cc=willy@linux.intel.com \
/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.