Skip to content

Commit ea29548

Browse files
committed
Merge tag 'xarray-5.1-rc1' of git://git.infradead.org/users/willy/linux-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
2 parents f3124cc + 4a5c8d8 commit ea29548

File tree

7 files changed

+561
-260
lines changed

7 files changed

+561
-260
lines changed

Documentation/core-api/xarray.rst

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ which was at that index; if it returns the same entry which was passed as
8585

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

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

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

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

145+
By default, the lowest free entry is allocated starting from 0. If you
146+
want to allocate entries starting at 1, it is more efficient to use
147+
:c:func:`DEFINE_XARRAY_ALLOC1` or ``XA_FLAGS_ALLOC1``. If you want to
148+
allocate IDs up to a maximum, then wrap back around to the lowest free
149+
ID, you can use :c:func:`xa_alloc_cyclic`.
150+
145151
You cannot use ``XA_MARK_0`` with an allocating XArray as this mark
146152
is used to track whether an entry is free or not. The other marks are
147153
available for your use.
@@ -209,7 +215,6 @@ Assumes xa_lock held on entry:
209215
* :c:func:`__xa_erase`
210216
* :c:func:`__xa_cmpxchg`
211217
* :c:func:`__xa_alloc`
212-
* :c:func:`__xa_reserve`
213218
* :c:func:`__xa_set_mark`
214219
* :c:func:`__xa_clear_mark`
215220

drivers/infiniband/core/device.c

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -668,19 +668,10 @@ static int assign_name(struct ib_device *device, const char *name)
668668
}
669669
strlcpy(device->name, dev_name(&device->dev), IB_DEVICE_NAME_MAX);
670670

671-
/* Cyclically allocate a user visible ID for the device */
672-
device->index = last_id;
673-
ret = xa_alloc(&devices, &device->index, INT_MAX, device, GFP_KERNEL);
674-
if (ret == -ENOSPC) {
675-
device->index = 0;
676-
ret = xa_alloc(&devices, &device->index, INT_MAX, device,
677-
GFP_KERNEL);
678-
}
679-
if (ret)
680-
goto out;
681-
last_id = device->index + 1;
682-
683-
ret = 0;
671+
ret = xa_alloc_cyclic(&devices, &device->index, device, xa_limit_31b,
672+
&last_id, GFP_KERNEL);
673+
if (ret > 0)
674+
ret = 0;
684675

685676
out:
686677
up_write(&devices_rwsem);
@@ -1059,14 +1050,15 @@ static int assign_client_id(struct ib_client *client)
10591050
* to get the LIFO order. The extra linked list can go away if xarray
10601051
* learns to reverse iterate.
10611052
*/
1062-
if (list_empty(&client_list))
1053+
if (list_empty(&client_list)) {
10631054
client->client_id = 0;
1064-
else
1065-
client->client_id =
1066-
list_last_entry(&client_list, struct ib_client, list)
1067-
->client_id;
1068-
ret = xa_alloc(&clients, &client->client_id, INT_MAX, client,
1069-
GFP_KERNEL);
1055+
} else {
1056+
struct ib_client *last;
1057+
1058+
last = list_last_entry(&client_list, struct ib_client, list);
1059+
client->client_id = last->client_id + 1;
1060+
}
1061+
ret = xa_insert(&clients, client->client_id, client, GFP_KERNEL);
10701062
if (ret)
10711063
goto out;
10721064

drivers/infiniband/core/restrack.c

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,6 @@
1313
#include "cma_priv.h"
1414
#include "restrack.h"
1515

16-
static int rt_xa_alloc_cyclic(struct xarray *xa, u32 *id, void *entry,
17-
u32 *next)
18-
{
19-
int err;
20-
21-
*id = *next;
22-
if (*next == U32_MAX)
23-
*id = 0;
24-
25-
xa_lock(xa);
26-
err = __xa_alloc(xa, id, U32_MAX, entry, GFP_KERNEL);
27-
if (err && *next != U32_MAX) {
28-
*id = 0;
29-
err = __xa_alloc(xa, id, *next, entry, GFP_KERNEL);
30-
}
31-
32-
if (!err)
33-
*next = *id + 1;
34-
xa_unlock(xa);
35-
return err;
36-
}
37-
3816
/**
3917
* rdma_restrack_init() - initialize and allocate resource tracking
4018
* @dev: IB device
@@ -226,7 +204,8 @@ static void rdma_restrack_add(struct rdma_restrack_entry *res)
226204
kref_init(&res->kref);
227205
init_completion(&res->comp);
228206
if (res->type != RDMA_RESTRACK_QP)
229-
ret = rt_xa_alloc_cyclic(&rt->xa, &res->id, res, &rt->next_id);
207+
ret = xa_alloc_cyclic(&rt->xa, &res->id, res, xa_limit_32b,
208+
&rt->next_id, GFP_KERNEL);
230209
else {
231210
/* Special case to ensure that LQPN points to right QP */
232211
struct ib_qp *qp = container_of(res, struct ib_qp, res);

fs/nilfs2/btnode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
189189
*/
190190
if (!err)
191191
return 0;
192-
else if (err != -EEXIST)
192+
else if (err != -EBUSY)
193193
goto failed_unlock;
194194

195195
err = invalidate_inode_pages2_range(btnc, newkey, newkey);

0 commit comments

Comments
 (0)