Skip to content

Commit

Permalink
Merge tag 'xarray-5.1-rc1' of git://git.infradead.org/users/willy/lin…
Browse files Browse the repository at this point in the history
…ux-dax

Pull XArray updates from Matthew Wilcox:
 "This pull request changes the xa_alloc() API. I'm only aware of one
  subsystem that has started trying to use it, and we agree on the fixup
  as part of the merge.

  The xa_insert() error code also changed to match xa_alloc() (EEXIST to
  EBUSY), and I added xa_alloc_cyclic(). Beyond that, the usual
  bugfixes, optimisations and tweaking.

  I now have a git tree with all users of the radix tree and IDR
  converted over to the XArray that I'll be feeding to maintainers over
  the next few weeks"

* tag 'xarray-5.1-rc1' of git://git.infradead.org/users/willy/linux-dax:
  XArray: Fix xa_reserve for 2-byte aligned entries
  XArray: Fix xa_erase of 2-byte aligned entries
  XArray: Use xa_cmpxchg to implement xa_reserve
  XArray: Fix xa_release in allocating arrays
  XArray: Mark xa_insert and xa_reserve as must_check
  XArray: Add cyclic allocation
  XArray: Redesign xa_alloc API
  XArray: Add support for 1s-based allocation
  XArray: Change xa_insert to return -EBUSY
  XArray: Update xa_erase family descriptions
  XArray tests: RCU lock prohibits GFP_KERNEL
  • Loading branch information
Linus Torvalds committed Mar 12, 2019
2 parents f3124cc + 4a5c8d8 commit ea29548
Show file tree
Hide file tree
Showing 7 changed files with 561 additions and 260 deletions.
15 changes: 10 additions & 5 deletions Documentation/core-api/xarray.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ which was at that index; if it returns the same entry which was passed as

If you want to only store a new entry to an index if the current entry
at that index is ``NULL``, you can use :c:func:`xa_insert` which
returns ``-EEXIST`` if the entry is not empty.
returns ``-EBUSY`` if the entry is not empty.

You can enquire whether a mark is set on an entry by using
:c:func:`xa_get_mark`. If the entry is not ``NULL``, you can set a mark
Expand Down Expand Up @@ -131,17 +131,23 @@ If you use :c:func:`DEFINE_XARRAY_ALLOC` to define the XArray, or
initialise it by passing ``XA_FLAGS_ALLOC`` to :c:func:`xa_init_flags`,
the XArray changes to track whether entries are in use or not.

You can call :c:func:`xa_alloc` to store the entry at any unused index
You can call :c:func:`xa_alloc` to store the entry at an unused index
in the XArray. If you need to modify the array from interrupt context,
you can use :c:func:`xa_alloc_bh` or :c:func:`xa_alloc_irq` to disable
interrupts while allocating the ID.

Using :c:func:`xa_store`, :c:func:`xa_cmpxchg` or :c:func:`xa_insert`
will mark the entry as being allocated. Unlike a normal XArray, storing
Using :c:func:`xa_store`, :c:func:`xa_cmpxchg` or :c:func:`xa_insert` will
also mark the entry as being allocated. Unlike a normal XArray, storing
``NULL`` will mark the entry as being in use, like :c:func:`xa_reserve`.
To free an entry, use :c:func:`xa_erase` (or :c:func:`xa_release` if
you only want to free the entry if it's ``NULL``).

By default, the lowest free entry is allocated starting from 0. If you
want to allocate entries starting at 1, it is more efficient to use
:c:func:`DEFINE_XARRAY_ALLOC1` or ``XA_FLAGS_ALLOC1``. If you want to
allocate IDs up to a maximum, then wrap back around to the lowest free
ID, you can use :c:func:`xa_alloc_cyclic`.

You cannot use ``XA_MARK_0`` with an allocating XArray as this mark
is used to track whether an entry is free or not. The other marks are
available for your use.
Expand Down Expand Up @@ -209,7 +215,6 @@ Assumes xa_lock held on entry:
* :c:func:`__xa_erase`
* :c:func:`__xa_cmpxchg`
* :c:func:`__xa_alloc`
* :c:func:`__xa_reserve`
* :c:func:`__xa_set_mark`
* :c:func:`__xa_clear_mark`

Expand Down
32 changes: 12 additions & 20 deletions drivers/infiniband/core/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,19 +668,10 @@ static int assign_name(struct ib_device *device, const char *name)
}
strlcpy(device->name, dev_name(&device->dev), IB_DEVICE_NAME_MAX);

/* Cyclically allocate a user visible ID for the device */
device->index = last_id;
ret = xa_alloc(&devices, &device->index, INT_MAX, device, GFP_KERNEL);
if (ret == -ENOSPC) {
device->index = 0;
ret = xa_alloc(&devices, &device->index, INT_MAX, device,
GFP_KERNEL);
}
if (ret)
goto out;
last_id = device->index + 1;

ret = 0;
ret = xa_alloc_cyclic(&devices, &device->index, device, xa_limit_31b,
&last_id, GFP_KERNEL);
if (ret > 0)
ret = 0;

out:
up_write(&devices_rwsem);
Expand Down Expand Up @@ -1059,14 +1050,15 @@ static int assign_client_id(struct ib_client *client)
* to get the LIFO order. The extra linked list can go away if xarray
* learns to reverse iterate.
*/
if (list_empty(&client_list))
if (list_empty(&client_list)) {
client->client_id = 0;
else
client->client_id =
list_last_entry(&client_list, struct ib_client, list)
->client_id;
ret = xa_alloc(&clients, &client->client_id, INT_MAX, client,
GFP_KERNEL);
} else {
struct ib_client *last;

last = list_last_entry(&client_list, struct ib_client, list);
client->client_id = last->client_id + 1;
}
ret = xa_insert(&clients, client->client_id, client, GFP_KERNEL);
if (ret)
goto out;

Expand Down
25 changes: 2 additions & 23 deletions drivers/infiniband/core/restrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,6 @@
#include "cma_priv.h"
#include "restrack.h"

static int rt_xa_alloc_cyclic(struct xarray *xa, u32 *id, void *entry,
u32 *next)
{
int err;

*id = *next;
if (*next == U32_MAX)
*id = 0;

xa_lock(xa);
err = __xa_alloc(xa, id, U32_MAX, entry, GFP_KERNEL);
if (err && *next != U32_MAX) {
*id = 0;
err = __xa_alloc(xa, id, *next, entry, GFP_KERNEL);
}

if (!err)
*next = *id + 1;
xa_unlock(xa);
return err;
}

/**
* rdma_restrack_init() - initialize and allocate resource tracking
* @dev: IB device
Expand Down Expand Up @@ -226,7 +204,8 @@ static void rdma_restrack_add(struct rdma_restrack_entry *res)
kref_init(&res->kref);
init_completion(&res->comp);
if (res->type != RDMA_RESTRACK_QP)
ret = rt_xa_alloc_cyclic(&rt->xa, &res->id, res, &rt->next_id);
ret = xa_alloc_cyclic(&rt->xa, &res->id, res, xa_limit_32b,
&rt->next_id, GFP_KERNEL);
else {
/* Special case to ensure that LQPN points to right QP */
struct ib_qp *qp = container_of(res, struct ib_qp, res);
Expand Down
2 changes: 1 addition & 1 deletion fs/nilfs2/btnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
*/
if (!err)
return 0;
else if (err != -EEXIST)
else if (err != -EBUSY)
goto failed_unlock;

err = invalidate_inode_pages2_range(btnc, newkey, newkey);
Expand Down
Loading

0 comments on commit ea29548

Please sign in to comment.