XArray: Add xa_cmpxchg_irq and xa_cmpxchg_bh
These convenience wrappers match the other _irq and _bh wrappers we already have. It turns out I'd already open-coded xa_cmpxchg_irq() in the shmem code, so convert that. Signed-off-by: Matthew Wilcox <willy@infradead.org>
This commit is contained in:
Родитель
eff3860bbf
Коммит
55f3f7eab7
|
@ -187,6 +187,8 @@ Takes xa_lock internally:
|
||||||
* :c:func:`xa_erase_bh`
|
* :c:func:`xa_erase_bh`
|
||||||
* :c:func:`xa_erase_irq`
|
* :c:func:`xa_erase_irq`
|
||||||
* :c:func:`xa_cmpxchg`
|
* :c:func:`xa_cmpxchg`
|
||||||
|
* :c:func:`xa_cmpxchg_bh`
|
||||||
|
* :c:func:`xa_cmpxchg_irq`
|
||||||
* :c:func:`xa_store_range`
|
* :c:func:`xa_store_range`
|
||||||
* :c:func:`xa_alloc`
|
* :c:func:`xa_alloc`
|
||||||
* :c:func:`xa_alloc_bh`
|
* :c:func:`xa_alloc_bh`
|
||||||
|
@ -263,7 +265,8 @@ using :c:func:`xa_lock_irqsave` in both the interrupt handler and process
|
||||||
context, or :c:func:`xa_lock_irq` in process context and :c:func:`xa_lock`
|
context, or :c:func:`xa_lock_irq` in process context and :c:func:`xa_lock`
|
||||||
in the interrupt handler. Some of the more common patterns have helper
|
in the interrupt handler. Some of the more common patterns have helper
|
||||||
functions such as :c:func:`xa_store_bh`, :c:func:`xa_store_irq`,
|
functions such as :c:func:`xa_store_bh`, :c:func:`xa_store_irq`,
|
||||||
:c:func:`xa_erase_bh` and :c:func:`xa_erase_irq`.
|
:c:func:`xa_erase_bh`, :c:func:`xa_erase_irq`, :c:func:`xa_cmpxchg_bh`
|
||||||
|
and :c:func:`xa_cmpxchg_irq`.
|
||||||
|
|
||||||
Sometimes you need to protect access to the XArray with a mutex because
|
Sometimes you need to protect access to the XArray with a mutex because
|
||||||
that lock sits above another mutex in the locking hierarchy. That does
|
that lock sits above another mutex in the locking hierarchy. That does
|
||||||
|
|
|
@ -553,6 +553,60 @@ static inline void *xa_cmpxchg(struct xarray *xa, unsigned long index,
|
||||||
return curr;
|
return curr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xa_cmpxchg_bh() - Conditionally replace an entry in the XArray.
|
||||||
|
* @xa: XArray.
|
||||||
|
* @index: Index into array.
|
||||||
|
* @old: Old value to test against.
|
||||||
|
* @entry: New value to place in array.
|
||||||
|
* @gfp: Memory allocation flags.
|
||||||
|
*
|
||||||
|
* This function is like calling xa_cmpxchg() except it disables softirqs
|
||||||
|
* while holding the array lock.
|
||||||
|
*
|
||||||
|
* Context: Any context. Takes and releases the xa_lock while
|
||||||
|
* disabling softirqs. May sleep if the @gfp flags permit.
|
||||||
|
* Return: The old value at this index or xa_err() if an error happened.
|
||||||
|
*/
|
||||||
|
static inline void *xa_cmpxchg_bh(struct xarray *xa, unsigned long index,
|
||||||
|
void *old, void *entry, gfp_t gfp)
|
||||||
|
{
|
||||||
|
void *curr;
|
||||||
|
|
||||||
|
xa_lock_bh(xa);
|
||||||
|
curr = __xa_cmpxchg(xa, index, old, entry, gfp);
|
||||||
|
xa_unlock_bh(xa);
|
||||||
|
|
||||||
|
return curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xa_cmpxchg_irq() - Conditionally replace an entry in the XArray.
|
||||||
|
* @xa: XArray.
|
||||||
|
* @index: Index into array.
|
||||||
|
* @old: Old value to test against.
|
||||||
|
* @entry: New value to place in array.
|
||||||
|
* @gfp: Memory allocation flags.
|
||||||
|
*
|
||||||
|
* This function is like calling xa_cmpxchg() except it disables interrupts
|
||||||
|
* while holding the array lock.
|
||||||
|
*
|
||||||
|
* Context: Process context. Takes and releases the xa_lock while
|
||||||
|
* disabling interrupts. May sleep if the @gfp flags permit.
|
||||||
|
* Return: The old value at this index or xa_err() if an error happened.
|
||||||
|
*/
|
||||||
|
static inline void *xa_cmpxchg_irq(struct xarray *xa, unsigned long index,
|
||||||
|
void *old, void *entry, gfp_t gfp)
|
||||||
|
{
|
||||||
|
void *curr;
|
||||||
|
|
||||||
|
xa_lock_irq(xa);
|
||||||
|
curr = __xa_cmpxchg(xa, index, old, entry, gfp);
|
||||||
|
xa_unlock_irq(xa);
|
||||||
|
|
||||||
|
return curr;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xa_insert() - Store this entry in the XArray unless another entry is
|
* xa_insert() - Store this entry in the XArray unless another entry is
|
||||||
* already present.
|
* already present.
|
||||||
|
|
|
@ -661,9 +661,7 @@ static int shmem_free_swap(struct address_space *mapping,
|
||||||
{
|
{
|
||||||
void *old;
|
void *old;
|
||||||
|
|
||||||
xa_lock_irq(&mapping->i_pages);
|
old = xa_cmpxchg_irq(&mapping->i_pages, index, radswap, NULL, 0);
|
||||||
old = __xa_cmpxchg(&mapping->i_pages, index, radswap, NULL, 0);
|
|
||||||
xa_unlock_irq(&mapping->i_pages);
|
|
||||||
if (old != radswap)
|
if (old != radswap)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
free_swap_and_cache(radix_to_swp_entry(radswap));
|
free_swap_and_cache(radix_to_swp_entry(radswap));
|
||||||
|
|
Загрузка…
Ссылка в новой задаче