diff mbox series

[for-next,1/9] RDMA/rxe: Fix handling sleepable in rxe_pool.c

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

Commit Message

Bob Pearson July 21, 2023, 8:50 p.m. UTC
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(-)

Comments

Jason Gunthorpe July 31, 2023, 6:08 p.m. UTC | #1
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 mbox series

Patch

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);