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

    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

    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

    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

    Matthew Wilcox
     
  • 0day picked up that I'd forgotten to add locking to this new test.

    Signed-off-by: Matthew Wilcox

    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

    Matthew Wilcox
     

06 Dec, 2018

2 commits


19 Nov, 2018

1 commit


17 Nov, 2018

1 commit


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

    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

    Matthew Wilcox
     

21 Oct, 2018

18 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

    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

    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

    Matthew Wilcox
     
  • Move this test to the in-kernel test suite, and enhance it to test
    several different orders.

    Signed-off-by: Matthew Wilcox

    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

    Matthew Wilcox
     
  • This is a 1:1 conversion. The major part of this patch is converting
    the test framework from userspace to kernel space and mirroring the
    algorithm now used in find_swap_entry().

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • We construct an XA_STATE and use it to delete the node with
    xas_store() rather than adding a special function for this unique
    use case. Includes a test that simulates this usage for the
    test suite.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • Add the optional ability to track which entries in an XArray are free
    and provide xa_alloc() to replace most of the functionality of the IDR.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • This function reserves a slot in the XArray for users which need
    to acquire multiple locks before storing their entry in the tree and
    so cannot use a plain xa_store().

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • This hopefully temporary function is useful for users who have not yet
    been converted to multi-index entries.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • This iterator iterates over each entry that is stored in the index or
    indices specified by the xa_state. This is intended for use for a
    conditional store of a multiindex entry, or to allow entries which are
    about to be removed from the xarray to be disposed of properly.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • The xas_next and xas_prev functions move the xas index by one position,
    and adjust the rest of the iterator state to match it. This is more
    efficient than calling xas_set() as it keeps the iterator at the leaves
    of the tree instead of walking the iterator from the root each time.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • This function frees all the internal memory allocated to the xarray
    and reinitialises it to be empty.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • The xa_for_each iterator allows the user to efficiently walk a range
    of the array, executing the loop body once for each entry in that
    range that matches the filter. This commit also includes xa_find()
    and xa_find_after() which are helper functions for xa_for_each() but
    may also be useful in their own right.

    In the xas family of functions, we have xas_for_each(), xas_find(),
    xas_next_entry(), xas_for_each_tagged(), xas_find_tagged(),
    xas_next_tagged() and xas_pause().

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • Like cmpxchg(), xa_cmpxchg will only store to the index if the current
    entry matches the old entry. It returns the current entry, which is
    usually more useful than the errno returned by radix_tree_insert().
    For the users who really only want the errno, the xa_insert() wrapper
    provides a more convenient calling convention.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • xa_store() differs from radix_tree_insert() in that it will overwrite an
    existing element in the array rather than returning an error. This is
    the behaviour which most users want, and those that want more complex
    behaviour generally want to use the xas family of routines anyway.

    For memory allocation, xa_store() will first attempt to request memory
    from the slab allocator; if memory is not immediately available, it will
    drop the xa_lock and allocate memory, keeping a pointer in the xa_state.
    It does not use the per-CPU cache, although those will continue to exist
    until all radix tree users are converted to the xarray.

    This patch also includes xa_erase() and __xa_erase() for a streamlined
    way to store NULL. Since there is no need to allocate memory in order
    to store a NULL in the XArray, we do not need to trouble the user with
    deciding what memory allocation flags to use.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • XArray marks are like the radix tree tags, only slightly more strongly
    typed. They are renamed in order to distinguish them from tagged
    pointers. This commit adds the basic get/set/clear operations.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • The xa_load function brings with it a lot of infrastructure; xa_empty(),
    xa_is_err(), and large chunks of the XArray advanced API that are used
    to implement xa_load.

    As the test-suite demonstrates, it is possible to use the XArray functions
    on a radix tree. The radix tree functions depend on the GFP flags being
    stored in the root of the tree, so it's not possible to use the radix
    tree functions on an XArray.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox