@@ -119,8 +119,10 @@ void rxe_pool_cleanup(struct rxe_pool *pool)
int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem,
bool sleepable)
{
- int err;
+ struct xarray *xa = &pool->xa;
+ unsigned long flags;
gfp_t gfp_flags;
+ int err;
if (atomic_inc_return(&pool->num_elem) > pool->max_elem)
goto err_cnt;
@@ -138,8 +140,10 @@ int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem,
if (sleepable)
might_sleep();
- err = xa_alloc_cyclic(&pool->xa, &elem->index, NULL, pool->limit,
+ xa_lock_irqsave(xa, flags);
+ err = __xa_alloc_cyclic(xa, &elem->index, NULL, pool->limit,
&pool->next, gfp_flags);
+ xa_unlock_irqrestore(xa, flags);
if (err < 0)
goto err_cnt;
@@ -179,6 +183,7 @@ int __rxe_cleanup(struct rxe_pool_elem *elem, bool sleepable)
struct rxe_pool *pool = elem->pool;
struct xarray *xa = &pool->xa;
static int timeout = RXE_POOL_TIMEOUT;
+ unsigned long flags;
int ret, err = 0;
void *xa_ret;
@@ -188,7 +193,9 @@ int __rxe_cleanup(struct rxe_pool_elem *elem, bool sleepable)
/* erase xarray entry to prevent looking up
* the pool elem from its index
*/
- xa_ret = xa_erase(xa, elem->index);
+ xa_lock_irqsave(xa, flags);
+ xa_ret = __xa_erase(xa, elem->index);
+ xa_unlock_irqrestore(xa, flags);
WARN_ON(xa_err(xa_ret));
/* if this is the last call to rxe_put complete the
@@ -249,9 +256,13 @@ int __rxe_put(struct rxe_pool_elem *elem)
void __rxe_finalize(struct rxe_pool_elem *elem, bool sleepable)
{
- void *xa_ret;
gfp_t gfp_flags = sleepable ? GFP_KERNEL : GFP_ATOMIC;
+ struct xarray *xa = &elem->pool->xa;
+ unsigned long flags;
+ void *xa_ret;
- xa_ret = xa_store(&elem->pool->xa, elem->index, elem, gfp_flags);
+ xa_lock_irqsave(xa, flags);
+ xa_ret = __xa_store(xa, elem->index, elem, gfp_flags);
+ xa_unlock_irqrestore(xa, flags);
WARN_ON(xa_err(xa_ret));
}
The kernel rdma verbs API calls are not documented to require that the caller be in process context and it is well known that the address handle calls sometimes are in interrupt context while the other ones are in process context. If we replace the xarray spin_lock in the rxe_pool APIs by irqsave spin_locks we make most of the verbs API calls safe in any context. This patch replaces the xa locks with xa_lock_irqsave. Fixes: 3225717f6dfa ("RDMA/rxe: Replace red-black trees by xarrays") Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com> --- drivers/infiniband/sw/rxe/rxe_pool.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)