Message ID | 20220417024343.568777-2-yanjun.zhu@linux.dev (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | [PATCHv5,1/2] RDMA/rxe: Fix a dead lock problem | expand |
On Sat, Apr 16, 2022 at 10:43:43PM -0400, yanjun.zhu@linux.dev wrote: > From: Zhu Yanjun <yanjun.zhu@linux.dev> > > The function __rxe_add_to_pool is called on different path, and the > requirement of the locks is different. The function rxe_create_ah > requires xa_lock_irqsave/irqrestore while others only require xa_lock_irq. > > Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev> > V1->V2: Use pool type instead of gfp_t; > drivers/infiniband/sw/rxe/rxe_pool.c | 18 +++++++++++++----- > 1 file changed, 13 insertions(+), 5 deletions(-) > > diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c > index f1f06dc7e64f..5b097d6666eb 100644 > +++ b/drivers/infiniband/sw/rxe/rxe_pool.c > @@ -157,7 +157,6 @@ void *rxe_alloc(struct rxe_pool *pool) > int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem) > { > int err; > - unsigned long flags; > > if (WARN_ON(pool->flags & RXE_POOL_ALLOC)) > return -EINVAL; > @@ -169,10 +168,19 @@ int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem) > elem->obj = (u8 *)elem - pool->elem_offset; > kref_init(&elem->ref_cnt); > > - xa_lock_irqsave(&pool->xa, flags); > - err = __xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit, > - &pool->next, GFP_ATOMIC); > - xa_unlock_irqrestore(&pool->xa, flags); > + if (pool->type == RXE_TYPE_AH) { > + unsigned long flags; > + > + xa_lock_irqsave(&pool->xa, flags); > + err = __xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit, > + &pool->next, GFP_ATOMIC); > + xa_unlock_irqrestore(&pool->xa, flags); This is still not right - you have to test RDMA_CREATE_AH_SLEEPABLE for the AH path as well. Jason
diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c index f1f06dc7e64f..5b097d6666eb 100644 --- a/drivers/infiniband/sw/rxe/rxe_pool.c +++ b/drivers/infiniband/sw/rxe/rxe_pool.c @@ -157,7 +157,6 @@ void *rxe_alloc(struct rxe_pool *pool) int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem) { int err; - unsigned long flags; if (WARN_ON(pool->flags & RXE_POOL_ALLOC)) return -EINVAL; @@ -169,10 +168,19 @@ int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem) elem->obj = (u8 *)elem - pool->elem_offset; kref_init(&elem->ref_cnt); - xa_lock_irqsave(&pool->xa, flags); - err = __xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit, - &pool->next, GFP_ATOMIC); - xa_unlock_irqrestore(&pool->xa, flags); + if (pool->type == RXE_TYPE_AH) { + unsigned long flags; + + xa_lock_irqsave(&pool->xa, flags); + err = __xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit, + &pool->next, GFP_ATOMIC); + xa_unlock_irqrestore(&pool->xa, flags); + } else { + xa_lock_irq(&pool->xa); + err = __xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit, + &pool->next, GFP_KERNEL); + xa_unlock_irq(&pool->xa); + } if (err) goto err_cnt;