summaryrefslogtreecommitdiffstats
path: root/tools/testing/radix-tree/main.c
diff options
context:
space:
mode:
authorMatthew Wilcox (Oracle) <willy@infradead.org>2020-03-12 17:29:11 -0400
committerMatthew Wilcox (Oracle) <willy@infradead.org>2020-03-12 17:42:08 -0400
commit7e934cf5ace1dceeb804f7493fa28bb697ed3c52 (patch)
treee79bea212e334e55d606a7f184113aa724c9aa71 /tools/testing/radix-tree/main.c
parent34eee836a9dd3e1987c10ed6afc7ece4131a993d (diff)
downloadlinux-7e934cf5ace1dceeb804f7493fa28bb697ed3c52.tar.bz2
xarray: Fix early termination of xas_for_each_marked
xas_for_each_marked() is using entry == NULL as a termination condition of the iteration. When xas_for_each_marked() is used protected only by RCU, this can however race with xas_store(xas, NULL) in the following way: TASK1 TASK2 page_cache_delete() find_get_pages_range_tag() xas_for_each_marked() xas_find_marked() off = xas_find_chunk() xas_store(&xas, NULL) xas_init_marks(&xas); ... rcu_assign_pointer(*slot, NULL); entry = xa_entry(off); And thus xas_for_each_marked() terminates prematurely possibly leading to missed entries in the iteration (translating to missing writeback of some pages or a similar problem). If we find a NULL entry that has been marked, skip it (unless we're trying to allocate an entry). Reported-by: Jan Kara <jack@suse.cz> CC: stable@vger.kernel.org Fixes: ef8e5717db01 ("page cache: Convert delete_batch to XArray") Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Diffstat (limited to 'tools/testing/radix-tree/main.c')
-rw-r--r--tools/testing/radix-tree/main.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/tools/testing/radix-tree/main.c b/tools/testing/radix-tree/main.c
index 7a22d6e3732e..f2cbc8e5b97c 100644
--- a/tools/testing/radix-tree/main.c
+++ b/tools/testing/radix-tree/main.c
@@ -311,6 +311,7 @@ int main(int argc, char **argv)
regression4_test();
iteration_test(0, 10 + 90 * long_run);
iteration_test(7, 10 + 90 * long_run);
+ iteration_test2(10 + 90 * long_run);
single_thread_tests(long_run);
/* Free any remaining preallocated nodes */