Skip to content

Commit 880b9df

Browse files
committed
Merge tag 'xarray-4.20-rc7' of git://git.infradead.org/users/willy/linux-dax
Pull XArray fixes from Matthew Wilcox: "Two bugfixes, each with test-suite updates, two improvements to the test-suite without associated bugs, and one patch adding a missing API" * tag 'xarray-4.20-rc7' of git://git.infradead.org/users/willy/linux-dax: XArray: Fix xa_alloc when id exceeds max XArray tests: Check iterating over multiorder entries XArray tests: Handle larger indices more elegantly XArray: Add xa_cmpxchg_irq and xa_cmpxchg_bh radix tree: Don't return retry entries from lookup
2 parents 65e08c5 + 4848361 commit 880b9df

File tree

10 files changed

+258
-54
lines changed

10 files changed

+258
-54
lines changed

Documentation/core-api/xarray.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ Takes xa_lock internally:
187187
* :c:func:`xa_erase_bh`
188188
* :c:func:`xa_erase_irq`
189189
* :c:func:`xa_cmpxchg`
190+
* :c:func:`xa_cmpxchg_bh`
191+
* :c:func:`xa_cmpxchg_irq`
190192
* :c:func:`xa_store_range`
191193
* :c:func:`xa_alloc`
192194
* :c:func:`xa_alloc_bh`
@@ -263,7 +265,8 @@ using :c:func:`xa_lock_irqsave` in both the interrupt handler and process
263265
context, or :c:func:`xa_lock_irq` in process context and :c:func:`xa_lock`
264266
in the interrupt handler. Some of the more common patterns have helper
265267
functions such as :c:func:`xa_store_bh`, :c:func:`xa_store_irq`,
266-
:c:func:`xa_erase_bh` and :c:func:`xa_erase_irq`.
268+
:c:func:`xa_erase_bh`, :c:func:`xa_erase_irq`, :c:func:`xa_cmpxchg_bh`
269+
and :c:func:`xa_cmpxchg_irq`.
267270

268271
Sometimes you need to protect access to the XArray with a mutex because
269272
that lock sits above another mutex in the locking hierarchy. That does

include/linux/xarray.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,60 @@ static inline void *xa_cmpxchg(struct xarray *xa, unsigned long index,
553553
return curr;
554554
}
555555

556+
/**
557+
* xa_cmpxchg_bh() - Conditionally replace an entry in the XArray.
558+
* @xa: XArray.
559+
* @index: Index into array.
560+
* @old: Old value to test against.
561+
* @entry: New value to place in array.
562+
* @gfp: Memory allocation flags.
563+
*
564+
* This function is like calling xa_cmpxchg() except it disables softirqs
565+
* while holding the array lock.
566+
*
567+
* Context: Any context. Takes and releases the xa_lock while
568+
* disabling softirqs. May sleep if the @gfp flags permit.
569+
* Return: The old value at this index or xa_err() if an error happened.
570+
*/
571+
static inline void *xa_cmpxchg_bh(struct xarray *xa, unsigned long index,
572+
void *old, void *entry, gfp_t gfp)
573+
{
574+
void *curr;
575+
576+
xa_lock_bh(xa);
577+
curr = __xa_cmpxchg(xa, index, old, entry, gfp);
578+
xa_unlock_bh(xa);
579+
580+
return curr;
581+
}
582+
583+
/**
584+
* xa_cmpxchg_irq() - Conditionally replace an entry in the XArray.
585+
* @xa: XArray.
586+
* @index: Index into array.
587+
* @old: Old value to test against.
588+
* @entry: New value to place in array.
589+
* @gfp: Memory allocation flags.
590+
*
591+
* This function is like calling xa_cmpxchg() except it disables interrupts
592+
* while holding the array lock.
593+
*
594+
* Context: Process context. Takes and releases the xa_lock while
595+
* disabling interrupts. May sleep if the @gfp flags permit.
596+
* Return: The old value at this index or xa_err() if an error happened.
597+
*/
598+
static inline void *xa_cmpxchg_irq(struct xarray *xa, unsigned long index,
599+
void *old, void *entry, gfp_t gfp)
600+
{
601+
void *curr;
602+
603+
xa_lock_irq(xa);
604+
curr = __xa_cmpxchg(xa, index, old, entry, gfp);
605+
xa_unlock_irq(xa);
606+
607+
return curr;
608+
}
609+
556610
/**
557611
* xa_insert() - Store this entry in the XArray unless another entry is
558612
* already present.

lib/radix-tree.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -784,11 +784,11 @@ void *__radix_tree_lookup(const struct radix_tree_root *root,
784784
while (radix_tree_is_internal_node(node)) {
785785
unsigned offset;
786786

787-
if (node == RADIX_TREE_RETRY)
788-
goto restart;
789787
parent = entry_to_node(node);
790788
offset = radix_tree_descend(parent, &node, index);
791789
slot = parent->slots + offset;
790+
if (node == RADIX_TREE_RETRY)
791+
goto restart;
792792
if (parent->shift == 0)
793793
break;
794794
}

0 commit comments

Comments
 (0)