Message ID | 20230721205021.5394-2-rpearsonhpe@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Jason Gunthorpe |
Headers | show |
Series | RDMA/rxe: Misc fixes and cleanups | expand |
On Fri, Jul 21, 2023 at 03:50:14PM -0500, Bob Pearson wrote: > Since the AH creation and destroy verbs APIs can be called in > interrupt context it is necessary to not sleep in these cases. > This was partially dealt with in previous fixes but some cases > remain where the code could still potentially sleep. > > This patch fixes this by extending the __rxe_finalize() call to > have a sleepable parameter and using this in the AH verbs calls. > It also fixes one call to rxe_cleanup which did not use the > sleepable API. > > Fixes: 215d0a755e1b ("RDMA/rxe: Stop lookup of partially built objects") > Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com> > --- > drivers/infiniband/sw/rxe/rxe_pool.c | 5 +++-- > drivers/infiniband/sw/rxe/rxe_pool.h | 5 +++-- > drivers/infiniband/sw/rxe/rxe_verbs.c | 11 ++++++----- > 3 files changed, 12 insertions(+), 9 deletions(-) > > diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c > index 6215c6de3a84..de0043b6d3f3 100644 > --- a/drivers/infiniband/sw/rxe/rxe_pool.c > +++ b/drivers/infiniband/sw/rxe/rxe_pool.c > @@ -247,10 +247,11 @@ int __rxe_put(struct rxe_pool_elem *elem) > return kref_put(&elem->ref_cnt, rxe_elem_release); > } > > -void __rxe_finalize(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; > > - xa_ret = xa_store(&elem->pool->xa, elem->index, elem, GFP_KERNEL); > + xa_ret = xa_store(&elem->pool->xa, elem->index, elem, gfp_flags); > WARN_ON(xa_err(xa_ret)); > } You don't need to do this, there is no allocation here, when you call xa_alloc_cyclic() it reserved all the memory necessary for this. Just add a comment and mark it GFP_ATOMIC. Jason
diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c index 6215c6de3a84..de0043b6d3f3 100644 --- a/drivers/infiniband/sw/rxe/rxe_pool.c +++ b/drivers/infiniband/sw/rxe/rxe_pool.c @@ -247,10 +247,11 @@ int __rxe_put(struct rxe_pool_elem *elem) return kref_put(&elem->ref_cnt, rxe_elem_release); } -void __rxe_finalize(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; - xa_ret = xa_store(&elem->pool->xa, elem->index, elem, GFP_KERNEL); + xa_ret = xa_store(&elem->pool->xa, elem->index, elem, gfp_flags); WARN_ON(xa_err(xa_ret)); } diff --git a/drivers/infiniband/sw/rxe/rxe_pool.h b/drivers/infiniband/sw/rxe/rxe_pool.h index ef2f6f88e254..d764c51ed6f7 100644 --- a/drivers/infiniband/sw/rxe/rxe_pool.h +++ b/drivers/infiniband/sw/rxe/rxe_pool.h @@ -77,7 +77,8 @@ int __rxe_cleanup(struct rxe_pool_elem *elem, bool sleepable); #define rxe_read(obj) kref_read(&(obj)->elem.ref_cnt) -void __rxe_finalize(struct rxe_pool_elem *elem); -#define rxe_finalize(obj) __rxe_finalize(&(obj)->elem) +void __rxe_finalize(struct rxe_pool_elem *elem, bool sleepable); +#define rxe_finalize(obj) __rxe_finalize(&(obj)->elem, true) +#define rxe_finalize_ah(obj, sleepable) __rxe_finalize(&(obj)->elem, sleepable) #endif /* RXE_POOL_H */ diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c index b899924b81eb..5e93dbac17b3 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -265,6 +265,7 @@ static int rxe_create_ah(struct ib_ah *ibah, struct rxe_dev *rxe = to_rdev(ibah->device); struct rxe_ah *ah = to_rah(ibah); struct rxe_create_ah_resp __user *uresp = NULL; + bool sleepable = init_attr->flags & RDMA_CREATE_AH_SLEEPABLE; int err, cleanup_err; if (udata) { @@ -276,8 +277,7 @@ static int rxe_create_ah(struct ib_ah *ibah, ah->is_user = false; } - err = rxe_add_to_pool_ah(&rxe->ah_pool, ah, - init_attr->flags & RDMA_CREATE_AH_SLEEPABLE); + err = rxe_add_to_pool_ah(&rxe->ah_pool, ah, sleepable); if (err) { rxe_dbg_dev(rxe, "unable to create ah"); goto err_out; @@ -307,12 +307,12 @@ static int rxe_create_ah(struct ib_ah *ibah, } rxe_init_av(init_attr->ah_attr, &ah->av); - rxe_finalize(ah); + rxe_finalize_ah(ah, sleepable); return 0; err_cleanup: - cleanup_err = rxe_cleanup(ah); + cleanup_err = rxe_cleanup_ah(ah, sleepable); if (cleanup_err) rxe_err_ah(ah, "cleanup failed, err = %d", cleanup_err); err_out: @@ -354,9 +354,10 @@ static int rxe_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) static int rxe_destroy_ah(struct ib_ah *ibah, u32 flags) { struct rxe_ah *ah = to_rah(ibah); + bool sleepable = flags & RDMA_DESTROY_AH_SLEEPABLE; int err; - err = rxe_cleanup_ah(ah, flags & RDMA_DESTROY_AH_SLEEPABLE); + err = rxe_cleanup_ah(ah, sleepable); if (err) rxe_err_ah(ah, "cleanup failed, err = %d", err);
Since the AH creation and destroy verbs APIs can be called in interrupt context it is necessary to not sleep in these cases. This was partially dealt with in previous fixes but some cases remain where the code could still potentially sleep. This patch fixes this by extending the __rxe_finalize() call to have a sleepable parameter and using this in the AH verbs calls. It also fixes one call to rxe_cleanup which did not use the sleepable API. Fixes: 215d0a755e1b ("RDMA/rxe: Stop lookup of partially built objects") Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com> --- drivers/infiniband/sw/rxe/rxe_pool.c | 5 +++-- drivers/infiniband/sw/rxe/rxe_pool.h | 5 +++-- drivers/infiniband/sw/rxe/rxe_verbs.c | 11 ++++++----- 3 files changed, 12 insertions(+), 9 deletions(-)