21 Oct, 2020
1 commit
-
Pull XArray updates from Matthew Wilcox:
- Fix the test suite after introduction of the local_lock
- Fix a bug in the IDA spotted by Coverity
- Change the API that allows the workingset code to delete a node
- Fix xas_reload() when dealing with entries that occupy multiple
indices- Add a few more tests to the test suite
- Fix an unsigned int being shifted into an unsigned long
* tag 'xarray-5.9' of git://git.infradead.org/users/willy/xarray:
XArray: Fix xas_create_range for ranges above 4 billion
radix-tree: fix the comment of radix_tree_next_slot()
XArray: Fix xas_reload for multi-index entries
XArray: Add private interface for workingset node deletion
XArray: Fix xas_for_each_conflict documentation
XArray: Test marked multiorder iterations
XArray: Test two more things about xa_cmpxchg
ida: Free allocated bitmap in error path
radix tree test suite: Fix compilation
17 Oct, 2020
2 commits
-
In order to use multi-index entries for huge pages in the page cache, we
need to be able to split a multi-index entry (eg if a file is truncated in
the middle of a huge page entry). This version does not support splitting
more than one level of the tree at a time. This is an acceptable
limitation for the page cache as we do not expect to support order-12
pages in the near future.[akpm@linux-foundation.org: export xas_split_alloc() to modules]
[willy@infradead.org: fix xarray split]
Link: https://lkml.kernel.org/r/20200910175450.GV6583@casper.infradead.org
[willy@infradead.org: fix xarray]
Link: https://lkml.kernel.org/r/20201001233943.GW20115@casper.infradead.orgSigned-off-by: Matthew Wilcox (Oracle)
Signed-off-by: Andrew Morton
Cc: "Kirill A . Shutemov"
Cc: Qian Cai
Cc: Song Liu
Link: https://lkml.kernel.org/r/20200903183029.14930-3-willy@infradead.org
Signed-off-by: Linus Torvalds -
Patch series "Fix read-only THP for non-tmpfs filesystems".
As described more verbosely in the [3/3] changelog, we can inadvertently
put an order-0 page in the page cache which occupies 512 consecutive
entries. Users are running into this if they enable the
READ_ONLY_THP_FOR_FS config option; see
https://bugzilla.kernel.org/show_bug.cgi?id=206569 and Qian Cai has also
reported it here:
https://lore.kernel.org/lkml/20200616013309.GB815@lca.pw/This is a rather intrusive way of fixing the problem, but has the
advantage that I've actually been testing it with the THP patches, which
means that it sees far more use than it does upstream -- indeed, Song has
been entirely unable to reproduce it. It also has the advantage that it
removes a few patches from my gargantuan backlog of THP patches.This patch (of 3):
This function returns the order of the entry at the index. We need this
because there isn't space in the shadow entry to encode its order.[akpm@linux-foundation.org: export xa_get_order to modules]
Signed-off-by: Matthew Wilcox (Oracle)
Signed-off-by: Andrew Morton
Cc: "Kirill A . Shutemov"
Cc: Qian Cai
Cc: Song Liu
Link: https://lkml.kernel.org/r/20200903183029.14930-1-willy@infradead.org
Link: https://lkml.kernel.org/r/20200903183029.14930-2-willy@infradead.org
Signed-off-by: Linus Torvalds
13 Oct, 2020
1 commit
-
Move the tricky bits of dealing with the XArray from the workingset
code to the XArray. Make it clear in the documentation that this is a
private interface, and only export it for the benefit of the test suite.Signed-off-by: Matthew Wilcox (Oracle)
08 Oct, 2020
1 commit
-
Demonstrate that starting a marked iteration partway through a marked
multi-order entry works.Signed-off-by: Matthew Wilcox (Oracle)
07 Oct, 2020
1 commit
-
1. If we xa_cmpxchg() an entry in, it marks the index as not free.
2. If we xa_cmpxchg() NULL in, it marks the index as free.Signed-off-by: Matthew Wilcox (Oracle)
01 Feb, 2020
2 commits
-
Inspired by the recent Coverity report, I looked for other places where
the offset wasn't being converted to an unsigned long before being
shifted, and I found one in xas_pause() when the entry being paused is
of order >32.Fixes: b803b42823d0 ("xarray: Add XArray iterators")
Signed-off-by: Matthew Wilcox (Oracle)
Cc: stable@vger.kernel.org -
Coverity pointed out that xas_sibling() was shifting xa_offset without
promoting it to an unsigned long first, so the shift could cause an
overflow and we'd get the wrong answer. The fix is obvious, and the
new test-case provokes UBSAN to report an error:
runtime error: shift exponent 60 is too large for 32-bit type 'int'Fixes: 19c30f4dd092 ("XArray: Fix xa_find_after with multi-index entries")
Reported-by: Bjorn Helgaas
Reported-by: Kees Cook
Signed-off-by: Matthew Wilcox (Oracle)
Cc: stable@vger.kernel.org
18 Jan, 2020
3 commits
-
If you call xas_find() with the initial index > max, it should have
returned NULL but was returning the entry at index.Signed-off-by: Matthew Wilcox (Oracle)
Cc: stable@vger.kernel.org -
If the entry is of an order which is a multiple of XA_CHUNK_SIZE,
the current detection of sibling entries does not work. Factor out
an xas_sibling() function to make xa_find_after() a little more
understandable, and write a new implementation that doesn't suffer from
the same bug.Signed-off-by: Matthew Wilcox (Oracle)
Cc: stable@vger.kernel.org -
If there is an entry at ULONG_MAX, xa_for_each() will overflow the
'index + 1' in xa_find_after() and wrap around to 0. Catch this case
and terminate the loop by returning NULL.Signed-off-by: Matthew Wilcox (Oracle)
Cc: stable@vger.kernel.org
09 Nov, 2019
1 commit
-
If we were unlucky enough to call xas_pause() when the index was at
ULONG_MAX (or a multi-slot entry which ends at ULONG_MAX), we would
wrap the index back around to 0 and restart the iteration from the
beginning. Use the XAS_BOUNDS state to indicate that we should just
stop the iteration.Signed-off-by: Matthew Wilcox (Oracle)
02 Jul, 2019
1 commit
-
If there is only a single entry at 0, the first time we call xas_next(),
we return the entry. Unfortunately, all subsequent times we call
xas_next(), we also return the entry at 0 instead of noticing that the
xa_index is now greater than zero. This broke find_get_pages_contig().Fixes: 64d3e9a9e0cc ("xarray: Step through an XArray")
Reported-by: Kent Overstreet
Signed-off-by: Matthew Wilcox (Oracle)
03 Jun, 2019
1 commit
-
A simple test which just checks that inserting an entry into an empty
array succeeds. Try various different interesting indices.Signed-off-by: Matthew Wilcox
22 Feb, 2019
2 commits
-
If we reserve index 0, the next entry to be stored there might be 2-byte
aligned. That means we have to create the root xa_node at the time of
reserving the initial entry.Signed-off-by: Matthew Wilcox
-
xas_store() was interpreting the entry it found in the array as a node
entry if the bottom two bits had value 2. That's only true if either
the entry is in the root node or in a non-leaf node.Signed-off-by: Matthew Wilcox
21 Feb, 2019
1 commit
-
xa_cmpxchg() was a little too magic in turning ZERO entries into NULL,
and would leave the entry set to the ZERO entry instead of releasing
it for future use. After careful review of existing users of
xa_cmpxchg(), change the semantics so that it does not translate either
incoming argument from NULL into ZERO entries.Add several tests to the test-suite to make sure this problem doesn't
come back.Reported-by: Jason Gunthorpe
Signed-off-by: Matthew Wilcox
09 Feb, 2019
1 commit
-
If the user doesn't care about the return value from xa_insert(), then
they should be using xa_store() instead. The point of xa_reserve() is
to get the return value early before taking another lock, so this should
also be __must_check.Signed-off-by: Matthew Wilcox
07 Feb, 2019
4 commits
-
This differs slightly from the IDR equivalent in five ways.
1. It can allocate up to UINT_MAX instead of being limited to INT_MAX,
like xa_alloc(). Also like xa_alloc(), it will write to the 'id'
pointer before placing the entry in the XArray.
2. The 'next' cursor is allocated separately from the XArray instead
of being part of the IDR. This saves memory for all the users which
do not use the cyclic allocation API and suits some users better.
3. It returns -EBUSY instead of -ENOSPC.
4. It will attempt to wrap back to the minimum value on memory allocation
failure as well as on an -EBUSY error, assuming that a user would
rather allocate a small ID than suffer an ID allocation failure.
5. It reports whether it has wrapped, which is important to some users.Signed-off-by: Matthew Wilcox
-
It was too easy to forget to initialise the start index. Add an
xa_limit data structure which can be used to pass min & max, and
define a couple of special values for common cases. Also add some
more tests cribbed from the IDR test suite. Change the return value
from -ENOSPC to -EBUSY to match xa_insert().Signed-off-by: Matthew Wilcox
-
A lot of places want to allocate IDs starting at 1 instead of 0.
While the xa_alloc() API supports this, it's not very efficient if lots
of IDs are allocated, due to having to walk down to the bottom of the
tree to see if ID 1 is available, then all the way over to the next
non-allocated ID. This method marks ID 0 as being occupied which wastes
one slot in the XArray, but preserves xa_empty() as working.Signed-off-by: Matthew Wilcox
-
Userspace translates EEXIST to "File exists" which isn't a very good
error message for the problem. "Device or resource busy" is a better
indication of what went wrong.Signed-off-by: Matthew Wilcox
05 Feb, 2019
1 commit
-
Drop and reacquire the RCU read lock while using GFP_KERNEL.
Reported-by: Li RongQing
Signed-off-by: Matthew Wilcox
15 Jan, 2019
1 commit
-
We do not currently check that the loop in xas_squash_marks() doesn't have
an off-by-one error in it. It didn't, but a patch which introduced an
off-by-one error wasn't caught by any existing test. Switch the roles
of XA_MARK_1 and XA_MARK_2 to catch that bug.Reported-by: Cyrill Gorcunov
Signed-off-by: Matthew Wilcox
07 Jan, 2019
4 commits
-
xa_insert() should treat reserved entries as occupied, not as available.
Also, it should treat requests to insert a NULL pointer as a request
to reserve the slot. Add xa_insert_bh() and xa_insert_irq() for
completeness.Signed-off-by: Matthew Wilcox
-
On m68k, statically allocated pointers may only be two-byte aligned.
This clashes with the XArray's method for tagging internal pointers.
Permit storing these pointers in single slots (ie not in multislots).Signed-off-by: Matthew Wilcox
-
There were three problems with this API:
1. It took too many arguments; almost all users wanted to iterate over
every element in the array rather than a subset.
2. It required that 'index' be initialised before use, and there's no
realistic way to make GCC catch that.
3. 'index' and 'entry' were the opposite way round from every other
member of the XArray APIs.So split it into three different APIs:
xa_for_each(xa, index, entry)
xa_for_each_start(xa, index, entry, start)
xa_for_each_marked(xa, index, entry, filter)Signed-off-by: Matthew Wilcox
-
0day picked up that I'd forgotten to add locking to this new test.
Signed-off-by: Matthew Wilcox
14 Dec, 2018
1 commit
-
Specifying a starting ID greater than the maximum ID isn't something
attempted very often, but it should fail. It was succeeding due to
xas_find_marked() returning the wrong error state, so add tests for
both xa_alloc() and xas_find_marked().Fixes: b803b42823d0 ("xarray: Add XArray iterators")
Signed-off-by: Matthew Wilcox
06 Dec, 2018
2 commits
-
There was no bug here, but there was no test coverage for this scenario.
Signed-off-by: Matthew Wilcox
-
xa_mk_value() only handles values up to LONG_MAX. I successfully hid
that inside xa_store_index() and xa_erase_index(), but it turned out I
also needed it for testing xa_alloc() on 32-bit machines. So extract
xa_mk_index() from the above two functions, and convert the non-constant
users of xa_mk_value() to xa_mk_index().Signed-off-by: Matthew Wilcox
19 Nov, 2018
1 commit
-
Lockdep caught me being sloppy in the test suite and failing to lock
the XArray appropriately.Reported-by: kernel test robot
Signed-off-by: Matthew Wilcox
17 Nov, 2018
1 commit
-
The test-suite caught these two mistakes when compiled for 32-bit.
I had only been running the test-suite in 64-bit mode.Signed-off-by: Matthew Wilcox
06 Nov, 2018
2 commits
-
The xa_reserve() function was a little unusual in that it attempted to
be callable for all kinds of locking scenarios. Make it look like the
other APIs with __xa_reserve, xa_reserve_bh and xa_reserve_irq variants.Signed-off-by: Matthew Wilcox
-
The following sequence of calls would result in an infinite loop in
xa_find_after():xa_store(xa, 0, x, GFP_KERNEL);
index = 0;
xa_for_each(xa, entry, index, ULONG_MAX, XA_PRESENT) { }xa_find_after() was confusing the situation where we found no entry in
the tree with finding a multiorder entry, so it would look for the
successor entry forever. Just check for this case explicitly. Includes
a few new checks in the test suite to be sure this doesn't reappear.Signed-off-by: Matthew Wilcox
21 Oct, 2018
5 commits
-
This version of xa_store_range() really only supports load and store.
Our only user only needs basic load and store functionality, so there's
no need to do the extra work to support marking and overlapping stores
correctly yet.Signed-off-by: Matthew Wilcox
-
This version is a little less thorough in order to be a little quicker,
but tests the important edge cases. Also test adding a multiorder entry
at a non-canonical index, and erasing it.Signed-off-by: Matthew Wilcox
-
Test this functionality inside the kernel as well as in userspace.
Also remove insert_bug() as there's no comparable thing to test
in the XArray code.Signed-off-by: Matthew Wilcox
-
Move this test to the in-kernel test suite, and enhance it to test
several different orders.Signed-off-by: Matthew Wilcox
-
The page cache was the only user of this interface and it has now
been converted to the XArray. Transform the test into a test of
xas_init_marks().Signed-off-by: Matthew Wilcox