mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
7e934cf5ac
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:
|
||
---|---|---|
.. | ||
generated | ||
linux | ||
.gitignore | ||
benchmark.c | ||
bitmap.c | ||
idr-test.c | ||
iteration_check_2.c | ||
iteration_check.c | ||
linux.c | ||
main.c | ||
Makefile | ||
multiorder.c | ||
regression1.c | ||
regression2.c | ||
regression3.c | ||
regression4.c | ||
regression.h | ||
tag_check.c | ||
test.c | ||
test.h | ||
xarray.c |